主页C++ Builder 资料C++ Builder 编程技巧图片处理jpg,gif,png,bmp之间转换
C++ Builder 串口控件
C++ Builder 编程技巧
字符串及文字处理
多媒体处理
图片处理
 • 显示 gif 图片和动画
 • bmp 转 gif 图片和动画
 • gif 的每一帧都提取出来
 • jpg,gif,png,bmp之间转换
 • 屏幕截图
 • 生成二维码
 • 识别二维码和条码
文件处理
界面处理
C++ Builder 操作指南
C++ Builder 参考手册
网友留言/技术支持
jpg, gif, png, bmp 之间的格式转换
 • jpg, png, bmp 转 gif 动画
 • jpg 转 gif, png, bmp
 • gif 转 jpg, png, bmp, 每一帧存为一个图片
 • png 转 jpg, gif, bmp
 • bmp 转 jpg, gif, png

本文内容用到的头文件:

类/模板 描述 头文件 (XE2 之后) 头文件 (XE 之前)
TGIFImage .gif 图片/动画 #include <Vcl.Imaging.GIFImg.hpp> #include <GIFImg.hpp>
TJPEGImage .jpg 图片/JPEG 图片 #include <Vcl.Imaging.jpeg.hpp> #include <jpeg.hpp>
TPngImage .png 图片 #include <Vcl.Imaging.pngimage.hpp> #include <pngimage.hpp>
TBitmap .bmp 图片/位图 #include <Vcl.Graphics.hpp> #include <Graphics.hpp>
TPicture 支持加载 .gif, .jpg, .png, .bmp, .emf, .tif 等 #include <Vcl.Graphics.hpp> #include <Graphics.hpp>
std::auto_ptr 自动指针 #include <memory> #include <memory>

TGIFImage, TJPEGImage, TPngImage, TBitmap 都是从 TGraphic 继承来的,他们之间可以通过 Assign 方法来互相复制显示的内容。

 

jpg, png, bmp 转 gif 动画

 • 这个例子是把 jpg, png, bmp 等几张图片合成一个 gif 动画,相当于循环播放这些图片的效果
 • 如果是单张图片,就是静态的 gif 图片,如果要指定透明颜色,请参考这两个例子

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  std::auto_ptr<TPicture>picture(new TPicture);
  std::auto_ptr<TGIFImage>gif(new TGIFImage);
  std::auto_ptr<TStringList>slFiles(new TStringList);

  // 图片文件名,显示时间 (时间单位为 0.01 秒)
  slFiles->AddPair(L"d:\\a.png", 20); // 第 1 帧:a.png, 显示时间:20 个单位 = 0.2 秒
  slFiles->AddPair(L"d:\\b.bmp", 30); // 第 2 帧:b.bmp, 显示时间:30 个单位 = 0.3 秒
  slFiles->AddPair(L"d:\\c.jpg", 50); // 第 3 帧:c.jpg, 显示时间:50 个单位 = 0.5 秒
  slFiles->AddPair(L"d:\\d.png", 50); // 第 4 帧:d.png, 显示时间:50 个单位 = 0.5 秒

  for(int i=0; i<slFiles->Count; i++)
   {
     TGIFFrame *lpFrame = new TGIFFrame(gif.get());   // gif 里面新增一个空白帧 lpFrame

     picture->LoadFromFile(slFiles->Names[i]);        // 加载第 i 个 图片文件
     lpFrame->Assign(picture->Graphic);               // 把图片的内容复制到 lpFrame 帧里面

     if(i==0)                                         // 第一帧要添加 gif 循环播放的次数
      {
        TGIFAppExtNSLoop *loop = new TGIFAppExtNSLoop(lpFrame);
        loop->Loops = 0;                              // 0 为无限次循环,>0 为实际循环次数
      }

     // 给每一帧添加这一帧显示的时间 // uǝɥɔ ɹoʇɔıʌ - /ɯoɔ·suɐɟddɔ·ʍʍʍ//:dʇʇɥ
     TGIFGraphicControlExtension *gce = new TGIFGraphicControlExtension(lpFrame);
     gce->Delay = slFiles->ValueFromIndex[i].ToInt(); // 这一帧的显示时间为第 i 个图片的显示时间
   }

  gif->SaveToFile(L"d:\\test.gif");                   // 保存 gif 到文件 d:\\test.gif
}

 

jpg 转 gif, png, bmp

void __fastcall TForm1::Button2Click(TObject *Sender)
{
  std::auto_ptr<TJPEGImage>jpg(new TJPEGImage);
  std::auto_ptr<TGIFImage>gif(new TGIFImage);
  std::auto_ptr<TPngImage>png(new TPngImage);
  std::auto_ptr<TBitmap>bmp(new TBitmap);

  jpg->LoadFromFile(L"D:\\a.jpg");  // 加载 a.jpg 图片
  bmp->Assign(jpg.get());           // jpg 转为 bmp
  gif->Assign(bmp.get());           // 再由 bmp 转为 gif
  png->Assign(bmp.get());           // 再由 bmp 转为 png

  bmp->SaveToFile(L"d:\\test.bmp"); // 保存 bmp 到 test.bmp
  gif->SaveToFile(L"d:\\test.gif"); // 保存 gif 到 test.gif
  png->SaveToFile(L"d:\\test.png"); // 保存 png 到 test.png
}

 

gif 转 jpg, png, bmp, 每一帧存为一个图片

void __fastcall TForm1::Button3Click(TObject *Sender)
{
  std::auto_ptr<TGIFImage>gif(new TGIFImage);
  std::auto_ptr<TBitmap>bmp(new TBitmap);
  std::auto_ptr<TPngImage>png(new TPngImage);
  std::auto_ptr<TJPEGImage>jpg(new TJPEGImage);
  // Copyright © Victor Chen, http://www.cppfans.com/
  gif->LoadFromFile(L"D:\\a.gif");                          // 加载 a.gif
  for(int i=0; i<gif->Images->Count; i++)                   // 一共有 gif->Images->Count 帧
   {
     TGIFFrame *lpFrame = gif->Images->Frames[i];           // 第 i 帧
     if(i==0)
       bmp->Assign(lpFrame);                                // 第一帧是完整的图片
     else                                                   // 之后的帧需要画在前一帧上才是完整的图片
       lpFrame->Draw(bmp->Canvas,TRect(0,0,bmp->Width,bmp->Height),true,true);
     bmp->SaveToFile(String().sprintf(L"d:\\b%02d.bmp",i)); // 第 i 帧存为第 i 个 bmp 文件

     png->Assign(bmp.get());
     png->SaveToFile(String().sprintf(L"d:\\p%02d.png",i)); // 第 i 帧存为第 i 个 png 文件

     jpg->Assign(bmp.get());
     jpg->SaveToFile(String().sprintf(L"d:\\j%02d.jpg",i)); // 第 i 帧存为第 i 个 jpg 文件
   }
}

 

png 转 jpg, gif, bmp

void __fastcall TForm1::Button4Click(TObject *Sender)
{
  std::auto_ptr<TPngImage>png(new TPngImage);
  std::auto_ptr<TJPEGImage>jpg(new TJPEGImage);
  std::auto_ptr<TGIFImage>gif(new TGIFImage);
  std::auto_ptr<TBitmap>bmp(new TBitmap);

  png->LoadFromFile(L"D:\\a.png");             // 加载 a.png 图片

// bmp->Assign(png.get());                     // png 转为 bmp, 这句注释掉了,因为:
// 如果 png 有 Alpha 通道,是半透明的,那么直接 Assign 到 bmp 里面是黑背景的
// 如果需要指定一个背景颜色,就需要先把和 png 同样大小的 bmp 填充为指定的背景色
// 然后把 png 输出到背景色的 bmp 上,就达到了设定背景颜色的效果
  // Copyright © Victor Chen, http://www.cppfans.com/
  TColor clBkgnd = TColor(RGB(255,255,255));   // 背景色为白色 R=255, G=255, B=255
  TRect rcBmp(0, 0, png->Width, png->Height);  // bmp 的大小和 png 的大小相同

  bmp->PixelFormat = pf32bit;                  // bmp 设定为 32 位像素格式
  bmp->SetSize(rcBmp.Width(), rcBmp.Height()); // bmp 的大小和 png 的大小相同
  bmp->Canvas->Brush->Style = bsSolid;         // 用 bsSolid 刷子填充 bmp
  bmp->Canvas->Brush->Color = clBkgnd;         // 指定刷子的颜色为背景颜色
  bmp->Canvas->FillRect(rcBmp);                // bmp 填充为背景色
  bmp->Canvas->Draw(0,0,png.get());            // 把 png 输出到背景颜色的 bmp 上

  jpg->Assign(bmp.get());                      // 再由 bmp 转为 jpg
  gif->Assign(bmp.get());                      // 再由 bmp 转为 gif

  bmp->SaveToFile(L"d:\\test.bmp");            // 保存 bmp 到 test.bmp
  jpg->SaveToFile(L"d:\\test.jpg");            // 保存 jpg 到 test.jpg
  gif->SaveToFile(L"d:\\test.gif");            // 保存 gif 到 test.gif
}

 

bmp 转 jpg, gif, png

void __fastcall TForm1::Button15Click(TObject *Sender)
{
  std::auto_ptr<TBitmap>bmp(new TBitmap);
  std::auto_ptr<TJPEGImage>jpg(new TJPEGImage);
  std::auto_ptr<TGIFImage>gif(new TGIFImage);
  std::auto_ptr<TPngImage>png(new TPngImage);

  bmp->LoadFromFile(L"D:\\a.bmp");  // 加载 a.bmp 图片
  jpg->Assign(bmp.get());           // bmp 转为 jpg
  gif->Assign(bmp.get());           // bmp 转为 gif
  png->Assign(bmp.get());           // bmp 转为 png

  jpg->SaveToFile(L"d:\\test.jpg"); // 保存 jpg 到 test.jpg
  gif->SaveToFile(L"d:\\test.gif"); // 保存 gif 到 test.gif
  png->SaveToFile(L"d:\\test.png"); // 保存 png 到 test.png
}

 

◤上一页:gif 的每一帧都提取出来下一页:屏幕截图

C++ 爱好者 -- Victor Chen 的个人网站 www.cppfans.com 辽ICP备11016859号