科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件GDI+在Delphi程序的应用:多帧(页)图像的分解与合成

GDI+在Delphi程序的应用:多帧(页)图像的分解与合成

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

本文简单介绍多帧(页)图片分解与合成的例子。还有,TEncoderParameters是个封装图像编码器参数TEncoderParameter的数组类型结构,成员包括TEncoderParameter类型数组和数组个数。

作者: maozefa 来源:Csdn博客 2007年12月26日

关键字: GDI+ Delphi 分解 合成

  • 评论
  • 分享微博
  • 分享邮件

在GDI+支持的各种图像格式,gif格式和tiff格式图像可包含多帧(页)图片,GDI+可以很方便的分解和合成多帧(页)图片。

下面是个简单的多帧(页)图片分解与合成例子:

unit main1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

uses Gdiplus, GdipTypes, ActiveX;

{$R *.dfm}

// 把多帧图像分解为单图像保存到文件
procedure TForm1.Button1Click(Sender: TObject);
var
I, Count: Integer;
Clsid: TClsid;
Parameters: TEncoderParameters;
Quality: Integer;
Image: TGpImage;
GUID: TGUID;
begin
// 打开图像文件
Image := TGpImage.Create('hbmap108.gif');
try
// 获取图像所有帧维度的GUID,这里我们只取第一个
Image.GetFrameDimensionsList(@GUID, 1);
// 通过获取维度的GUID,取得图像的帧(页)数量
Count := Image.GetFrameCount(GUID);

// 下面设置自定义的编码参数,这里为1个参数
Parameters.Count := 1;
// 设置参数唯一标志的GUID,这里为编码品质
Parameters.Parameter[0].Guid := EncoderQuality;
// 设置参数值的数据类型为长整型
Parameters.Parameter[0].ValueType := EncoderParameterValueTypeLong;
Parameters.Parameter[0].NumberOfValues := 1;
// 设置参数的值:品质等级,最高为100,图像文件大小与品质成正比
Quality := 100;
Parameters.Parameter[0].Value := @Quality;

// 获取图像格式JPEG编码器的ClsID
GetEncoderClsid('image/jpeg', Clsid);

// 选择图像的各个帧为当前帧,并依次保存为jpg文件
for I := 0 to Count - 1 do
begin
Image.SelectActiveFrame(GUID, I);
Image.Save('Hb' + IntToStr(I) + '.jpg', Clsid, @Parameters);
end;
finally
Image.Free;
end;
end;

// 将单个图像合并为多帧图像,GDI+不支持GIF合成,只能合并为tiff格式
procedure TForm1.Button2Click(Sender: TObject);
var
Parameters: TEncoderParameters;
Value: TEncoderValue;
Img, tmp: TGpImage;
I: Integer;
Clsid: TClsid;
begin
// 下面设置自定义的编码参数,这里为1个参数
Parameters.Count := 1;
// 设置参数唯一标志的GUID,这里为保存标记
Parameters.Parameter[0].Guid := EncoderSaveFlag;
Parameters.Parameter[0].NumberOfValues := 1;
Parameters.Parameter[0].ValueType := EncoderParameterValueTypeLong;
// 设置参数的值。这里只把Value地址赋给了参数值,Value在后面具体赋值
Parameters.Parameter[0].Value := @Value;

// 打开第一个图像,这里的图像是前面代码分解后保存的jpg文件
Img := TGpImage.Create('Hb0.jpg');
try
// 获取图像格式tiff编码器的ClsID
GetEncoderClsid('image/tiff', Clsid);
// 在保存第一帧图像时,编码参数值设置为多帧
Value := EncoderValueMultiFrame;
// 保存第一帧图像
Img.Save('Hb.tif', Clsid, @Parameters);
// 保存随后的各帧图像时,编码参数值设置为维度页
Value := EncoderValueFrameDimensionPage;

// 依次打开后面的图像,保存到Hb.tif文件,本例图片为24帧
for I := 1 to 23 do
begin
tmp := TGpImage.Create('Hb' + IntToStr(I) + '.jpg');
try
Img.SaveAdd(tmp, @Parameters);
finally
tmp.Free;
end;
end;
finally
Img.Free;
end;

end;

end.

例子中已经做了较详细的注释,就不再对代码讲解了。但是有必要对编码参数作点说明:

TEncoderParameters是个封装图像编码器参数TEncoderParameter的数组类型结构,成员包括TEncoderParameter类型数组和数组个数。而编码参数类型TEncoderParameter定义如下:

//-----------------------------------------------------------------
// Encoder Parameter structure
//-----------------------------------------------------------------
TEncoderParameter = packed record
Guid: TGUID;   // 该参数全局唯一标识符 (GUID),
NumberOfValues: ULONG; // Value地址处包含的元素个数
ValueType: TEncoderParameterValueType; // Value所指值的数据类型
Value: Pointer;// 值的地址,可以为单值或者数组,具体根据Guid而定
PEncoderParameter = ^TEncoderParameter;

编码参数结构的Guid已经在GDI+中作了如下定义:

//---------------------------------------------------------------------------
// Encoder parameter sets  图像编码器参数类别设置
//---------------------------------------------------------------------------

EncoderCompression      : TGUID = '{e09d739d-ccd4-44ee-8eba-3fbf8be4fc58}'; // 压缩
{$EXTERNALSYM EncoderCompression}
EncoderColorDepth       : TGUID = '{66087055-ad66-4c7c-9a18-38a2310b8337}'; // 颜色深度
{$EXTERNALSYM EncoderColorDepth}
EncoderScanMethod       : TGUID = '{3a4e2661-3109-4e56-8536-42c156e7dcfa}'; // 扫描方法
{$EXTERNALSYM EncoderScanMethod}
EncoderVersion  : TGUID = '{24d18c76-814a-41a4-bf53-1c219cccf797}'; // 版本
{$EXTERNALSYM EncoderVersion}
EncoderRenderMethod     : TGUID = '{6d42c53a-229a-4825-8bb7-5c99e2b9a8b8}'; // 呈现方法
{$EXTERNALSYM EncoderRenderMethod}
EncoderQuality  : TGUID = '{1d5be4b5-fa4a-452d-9cdd-5db35105e7eb}'; // 质量
{$EXTERNALSYM EncoderQuality}
EncoderTransformation   : TGUID = '{8d0eb2d1-a58e-4ea8-aa14-108074b7b6f9}'; // 转换
{$EXTERNALSYM EncoderTransformation}
EncoderLuminanceTable   : TGUID = '{edb33bce-0266-4a77-b904-27216099e717}'; // 亮度表
{$EXTERNALSYM EncoderLuminanceTable}
EncoderChrominanceTable : TGUID = '{f2e455dc-09b3-4316-8260-676ada32481c}'; // 色度表
{$EXTERNALSYM EncoderChrominanceTable}
EncoderSaveFlag : TGUID = '{292266fc-ac40-47bf-8cfc-a85b89a655de}'; // 保存标志
{$EXTERNALSYM EncoderSaveFlag}

也就是说,我们可以在保存图像的同时,设置上述编码参数来满足我们的要求,如上面例子中分解图片时设置了质量参数;合成图像的时候设置了保存标志。但是很遗憾,不是每种图像编码器都支持上面参数的,如质量和转换参数就只有jpeg格式图像编码器支持,所以,如要用GDI+压缩图像旧只有JPEG格式才行。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章