文档章节

GdiPlus[55]: 图像(七) 图像编码的参数

涂孟超
 涂孟超
发布于 2014/09/26 15:31
字数 1694
阅读 9
收藏 0

通过 IGPImage.GetEncoderParameterList 可以获取指定编码格式的参数列表;

通过此列表可以遍历出各参数的指针: PGPNativeEncoderParameter(TGPNativeEncoderParameter 的指针);

TGPNativeEncoderParameter 是一个结构体:
TGPNativeEncoderParameter = record
  Guid: TGUID;                              { 参数标识 }
  NumberOfValues: ULONG;                    { 参数数组的元素数 }
  ValueType: TGPEncoderParameterValueType;  { 参数类型 }
  Value: Pointer;                           { 参数数据指针 }
end;

//其中的 TGPEncoderParameterValueType 是个枚举, 枚举值有:
EncoderParameterValueTypeByte          = 1 { 字节数组 }
EncoderParameterValueTypeASCII         = 2 { PAnsiChar }
EncoderParameterValueTypeShort         = 3 { Word }
EncoderParameterValueTypeLong          = 4 { Cardinal }
EncoderParameterValueTypeRational      = 5 { Cardinal/Cardinal; 第一个数是分子, 第二个数是分母 }
EncoderParameterValueTypeLongRange     = 6 { 一对 Cardinal, 表示一个数值范围 }
EncoderParameterValueTypeUndefined     = 7 { 可包含任何数据类型的字节数组 }
EncoderParameterValueTypeRationalRange = 8 { 四个整数: Cardinal/Cardinal, Cardinal/Cardinal }
EncoderParameterValueTypePointer       = 9 { 指针 }

//EncoderParameterValueTypeRationalRange 中的四个整数通过分数运算得到的两个值: 最小值...最大值.

 
 
 
 
 

 

 

  

每个编码器的参数肯定会有区别, 下面代码获取了 JPEG 编码器所能支持的参数信息:
uses GdiPlus;

procedure TForm1.Button1Click(Sender: TObject);
var
  Image: IGPImage;
  Parameters: IGPEncoderParameters;
  Param: PGPNativeEncoderParameter;
begin
  Image := TGPBitmap.Create(1, 1);
  Parameters := Image.GetEncoderParameterList(TGPImageFormat.Jpeg.CodecId);

  Memo1.Clear;
  for Param in Parameters do with Memo1.Lines do
  begin
    Add(Format('Guid: %s', [GUIDToString(Param.Guid)]));
    Add(Format('NumberOfValues: %d', [Param.NumberOfValues]));
    Add(Format('ValueType: %d', [Ord(Param.ValueType)]));
    Add(Format('Value: $%p', [Param.Value]));
    Add(EmptyStr);
  end;
end;
(* 结果:
  Guid: {8D0EB2D1-A58E-4EA8-AA14-108074B7B6F9}
  NumberOfValues: 5
  ValueType: 4
  Value: $00AD8190

  Guid: {1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB}
  NumberOfValues: 1
  ValueType: 6
  Value: $00AD81A4

  Guid: {EDB33BCE-0266-4A77-B904-27216099E717}
  NumberOfValues: 0
  ValueType: 3
  Value: $00AD81AC

  Guid: {F2E455DC-09B3-4316-8260-676ADA32481C}
  NumberOfValues: 0
  ValueType: 3
  Value: $00AD81AC
*)

 
 
 
 
 

 

 

  

IGPImage.GetEncoderParameterList 方法得到的类型是: IGPEncoderParameters;

IGPImage.Save 方法就有一个 IGPEncoderParameters 类型的默认参数, 通过它可以传入编码参数.

编码参数有很多类型, 譬如 EncoderQuality 是决定图片压缩比率的.

下面的例子在保存 JPG 文件时使用了三种不同的质量参数(压缩级别):



uses GdiPlus;

procedure TForm1.Button1Click(Sender: TObject);
var
  Prams: IGPEncoderParameters;
  Image: IGPImage;
  Graphics: IGPGraphics;
  Quality: Integer;
begin
  ChDir('C:\GdiPlusImg\');
  Image := TGPImage.Create('GrapeBunch.bmp');

  Prams := TGPEncoderParameters.Create;
  Quality := 1;
  Prams.Add(EncoderQuality, Quality);
  Image.Save('GrapeBunch_1.jpg', TGPImageFormat.Jpeg, Prams);

  Prams.Clear;
  Quality := 50;
  Prams.Add(EncoderQuality, Quality);
  Image.Save('GrapeBunch_50.jpg', TGPImageFormat.Jpeg, Prams);

  Prams.Clear;
  Quality := 100;
  Prams.Add(EncoderQuality, Quality);
  Image.Save('GrapeBunch_100.jpg', TGPImageFormat.Jpeg, Prams);

  //显示
  Graphics := TGPGraphics.Create(Handle);
  Image := TGPImage.Create('GrapeBunch_1.jpg');
  Graphics.DrawImage(Image, 10, 10);

  Graphics.TranslateTransform(Image.Width + 10, 0);
  Image := TGPImage.Create('GrapeBunch_50.jpg');
  Graphics.DrawImage(Image, 10, 10);

  Graphics.TranslateTransform(Image.Width + 10, 0);
  Image := TGPImage.Create('GrapeBunch_100.jpg');
  Graphics.DrawImage(Image, 10, 10);
end;

 
 
 
 
 

 

 

  

IGPEncoderParameters 的成员:
IGPEncoderParameters.GetEnumerator;
IGPEncoderParameters.Clear;
IGPEncoderParameters.Add();
IGPEncoderParameters.Count;
IGPEncoderParameters.Param[];
IGPEncoderParameters.NativeParams;

//其中的 Add 方法有多种重载, 这便于添加各种类型的数据; 参数类型常数:
EncoderCompression      { 压缩 }
EncoderColorDepth       { 颜色深度 }
EncoderScanMethod       { 扫描方法 }
EncoderVersion          { 版本 }
EncoderRenderMethod     { 呈现方法 }
EncoderQuality          { 质量 }
EncoderTransformation   { 转换 }
EncoderLuminanceTable   { 亮度表 }
EncoderChrominanceTable { 色度表 }
EncoderSaveFlag         { 保存标志 }
CodecIImageBytes        {  }
{ 下面是 GDI+1.1 才开始支持的: }
EncoderColorSpace       {  }
EncoderImageItems       {  }
EncoderSaveAsCMYK       {  }

 
 
 
 
 

 

 

  

五种编码器(BMP、JPEG、GIF、TIFF、PNG)分别能支持哪些 "参数类型" 呢?
支持的参数类型的参数又是什么格式的呢? 尽管 Add 方法已准备好了多种重载, 用哪个呢?

下面的程序列出了各种编码器的参数信息:

uses GdiPlus;

const
  ParamValueTypeArr: array[1..9] of string = (
    'ValueTypeByte',
    'ValueTypeASCII',
    'ValueTypeShort',
    'ValueTypeLong',
    'ValueTypeRational',
    'ValueTypeLongRange',
    'ValueTypeUndefined',
    'ValueTypeRationalRange',
    'ValueTypePointer'
  );

//自定义函数
function GetGuidName(g: TGUID): string;
var
  s: string;
begin
  s := EmptyStr;
  if IsEqualGUID(g, EncoderCompression) then s := 'EncoderCompression';
  if IsEqualGUID(g, EncoderColorDepth) then s := 'EncoderColorDepth';
  if IsEqualGUID(g, EncoderScanMethod) then s := 'EncoderScanMethod';
  if IsEqualGUID(g, EncoderVersion) then s := 'EncoderVersion';
  if IsEqualGUID(g, EncoderRenderMethod) then s := 'EncoderRenderMethod';
  if IsEqualGUID(g, EncoderQuality) then s := 'EncoderQuality';
  if IsEqualGUID(g, EncoderTransformation) then s := 'EncoderTransformation';
  if IsEqualGUID(g, EncoderLuminanceTable) then s := 'EncoderLuminanceTable';
  if IsEqualGUID(g, EncoderChrominanceTable) then s := 'EncoderChrominanceTable';
  if IsEqualGUID(g, EncoderSaveFlag) then s := 'EncoderSaveFlag';
  if IsEqualGUID(g, CodecIImageBytes) then s := 'CodecIImageBytes';
  {$IF (GDIPVER >= $0110)}
  if IsEqualGUID(g, EncoderColorSpace) then s := 'EncoderColorSpace';
  if IsEqualGUID(g, EncoderImageItems) then s := 'EncoderImageItems';
  if IsEqualGUID(g, EncoderSaveAsCMYK) then s := 'EncoderSaveAsCMYK';
  {$IFEND}
  Result := s;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Image: IGPImage;
  Parameters: IGPEncoderParameters;
  Param: PGPNativeEncoderParameter;
  Encoder: IGPImageCodecInfo;
begin
  Image := TGPBitmap.Create(1, 1);

  Memo1.Clear;
  for Encoder in TGPImageCodecInfo.GetImageEncoders do with Memo1.Lines do
  begin
    Parameters := Image.GetEncoderParameterList(Encoder.ClsId);

    Add('----------------------');
    Add(Format('编码器类型: %s', [Encoder.FormatDescription]));
    if Parameters.Count = 0 then
    begin
      Add('无参数');
      Add(EmptyStr);
      Continue;
    end;

    Add(Format('参数个数: %d', [Parameters.Count]));
    for Param in Parameters do
    begin
      Add(Format('参数类型: %s', [GetGuidName(Param.Guid)]));
      Add(Format('参数值类型: %s', [ParamValueTypeArr[Ord(Param.ValueType)]]));
      Add(Format('参数值个数: %d', [Param.NumberOfValues]));
      Add(Format('参数值指针: $%p', [Param.Value]));
      Add(EmptyStr);
    end;
  end;
end;
(* 显示结果:
  ----------------------
  编码器类型: BMP
  无参数

  ----------------------
  编码器类型: JPEG
  参数个数: 4
  参数类型: EncoderTransformation
  参数值类型: ValueTypeLong
  参数值个数: 5
  参数值指针: $00AD8190

  参数类型: EncoderQuality
  参数值类型: ValueTypeLongRange
  参数值个数: 1
  参数值指针: $00AD81A4

  参数类型: EncoderLuminanceTable
  参数值类型: ValueTypeShort
  参数值个数: 0
  参数值指针: $00AD81AC

  参数类型: EncoderChrominanceTable
  参数值类型: ValueTypeShort
  参数值个数: 0
  参数值指针: $00AD81AC

  ----------------------
  编码器类型: GIF
  无参数

  ----------------------
  编码器类型: TIFF
  参数个数: 3
  参数类型: EncoderCompression
  参数值类型: ValueTypeLong
  参数值个数: 5
  参数值指针: $00AD8190

  参数类型: EncoderColorDepth
  参数值类型: ValueTypeLong
  参数值个数: 5
  参数值指针: $00AD81A4

  参数类型: EncoderSaveFlag
  参数值类型: ValueTypeLong
  参数值个数: 1
  参数值指针: $00AD81B8

  ----------------------
  编码器类型: PNG
  无参数
*)

 
 
 
 
 

 

 

  

从上面例子可以看出:

BMP、GIF、PNG 三种编码器没有编码参数(GIF 在 GDI+1.1 中是不是支持还没有测试).

JPEG 支持:
EncoderTransformation (转换)
EncoderQuality (质量)
EncoderLuminanceTable (亮度表)
EncoderChrominanceTable (色度表)

TIFF 支持:
EncoderCompression (压缩)
EncoderColorDepth (颜色深度)
EncoderSaveFlag (保存标志)

进而可以得知:

JPEG 编码的参数类型 EncoderTransformation 的可选值是:
TGPEncoderValue(13): EncoderValueTransformRotate90
TGPEncoderValue(14): EncoderValueTransformRotate180
TGPEncoderValue(15): EncoderValueTransformRotate270
TGPEncoderValue(16): EncoderValueTransformFlipHorizontal
TGPEncoderValue(17): EncoderValueTransformFlipVertical

JPEG 编码的参数类型 EncoderQuality 的可选值是: 0..100

TIFF 编码的参数类型 EncoderCompression 的可选值是:
TGPEncoderValue(2): EncoderValueCompressionLZW
TGPEncoderValue(3): EncoderValueCompressionCCITT3
TGPEncoderValue(4): EncoderValueCompressionCCITT4
TGPEncoderValue(5): EncoderValueCompressionRle
TGPEncoderValue(6): EncoderValueCompressionNone

TIFF 编码的参数类型 EncoderColorDepth 的可选值是: 1,4,8,24,32

这些值可以从下面程序获取:

uses GdiPlus;

var
  Image: IGPImage;
  Parameters: IGPEncoderParameters;
  p: PCardinal;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Image := TGPBitmap.Create(1, 1);
end;

{$PointerMath On}
procedure TForm1.Button1Click(Sender: TObject);
begin
  Parameters := Image.GetEncoderParameterList(TGPImageFormat.Jpeg.CodecId);
  p := Parameters[0].Value; { EncoderTransformation }
  ShowMessageFmt('%d,%d,%d,%d,%d', [p[0],p[1],p[2],p[3],p[4]]); { 13,14,15,16,17 }
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Parameters := Image.GetEncoderParameterList(TGPImageFormat.Jpeg.CodecId);
  p := Parameters[1].Value; { EncoderQuality }
  ShowMessageFmt('%d..%d', [p[0],p[1]]); { 0..100 }
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  Parameters := Image.GetEncoderParameterList(TGPImageFormat.Tiff.CodecId);
  p := Parameters[0].Value; { EncoderCompression }
  ShowMessageFmt('%d,%d,%d,%d,%d', [p[0],p[1],p[2],p[3],p[4]]); { 2,3,5,4,6 }
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
  Parameters := Image.GetEncoderParameterList(TGPImageFormat.Tiff.CodecId);
  p := Parameters[1].Value; { EncoderColorDepth }
  ShowMessageFmt('%d,%d,%d,%d,%d', [p[0],p[1],p[2],p[3],p[4]]); { 1,4,8,24,32 }
end;

 
 
 
 
 

 

 

  

下面例子通过设置 JPEG 的 EncoderTransformation 编码参数, 保存了旋转后的图片:



uses GdiPlus;

procedure TForm1.Button1Click(Sender: TObject);
var
  Graphics: IGPGraphics;
  Prams: IGPEncoderParameters;
  Image: IGPImage;
begin
  ChDir('C:\GdiPlusImg\');
  Image := TGPImage.Create('Grapes.jpg');

  Prams := TGPEncoderParameters.Create;
  Prams.Add(EncoderTransformation, EncoderValueTransformRotate90);
  Image.Save('Grapes_Rotate90.jpg', TGPImageFormat.Jpeg, Prams);

  Graphics := TGPGraphics.Create(Handle);
  Graphics.DrawImage(Image, 10, 10, Image.Width, Image.Height);
end;

//为什么只有 JPEG 提供这种编码参数呢? 因为 jpg 文件在自动保存过程中会降低品质, 通过这种变换则不会.

 
 
 
 
 

 

 

  

另外:

1、编码参数值类型很多是 Cardinal, 这都是官方资料上的; 但 Add 函数中要的是 Integer 类型.

2、从上面获取的信息可以知道, GDI+1.0 还无法写入 gif 动画; GDI+1.1 能不能还没有测试.

3、通过设置 TIFF 编码器的 EncoderSaveFlag 类型参数可保存多页的 TIFF 文件, 下次接上.

本文转载自:http://www.cnblogs.com/del/archive/2009/12/29/1635265.html

涂孟超
粉丝 12
博文 2011
码字总数 14107
作品 0
深圳
程序员
私信 提问
VC实现多格式图像的转换

色彩鲜艳漂亮的高品质图像,一个个形象生动的Windows图标,高速运动、活灵活现的三维动画,这些无一不显示出程序设计者的艺术才华。在程序设计中,图像处理已经成为每个程序员的必修课。 在V...

余二五
2017/11/06
0
0

hjimce算法类博文目录 个人博客:http://blog.csdn.net/hjimce 个人qq:1393852684 知乎:https://www.zhihu.com/people/huang-jin-chi-28/activities 一、深度学习 深度学习(七十)darknet...

hjimce
2016/01/24
0
0
Wine 1.1.21 发布

Wine 1.1.21 现已发布。本版本主要带来了以下改进: 初步支持 shader model 4 能够从 X11 程序中复制/粘贴图像 对 GDIPlus 进行了改善 winemaker 支持 64 位 有关此版本的更新详情,可以查阅...

红薯
2009/05/10
144
0
“我爱智能”原创性博客索引

不知不觉,博客也写出了一点小体系,新的阶段已经开始,未来希望再接再厉继续补充这一体系,在成长中写博客,在博客中成长,在此先做一个小的梳理,谢谢大家的支持。 一)关于深度学习系列 ...

on2way
2015/08/29
0
0
DotNetCore跨平台~System.DrawingCore部署Linux需要注意的

你在windows上使用图像组件没有任务问题,但部署到linux之后,将注意以下几点: 安装nuget包ZKWeb.System.Drawing 项目里还是引用System.DrawingCore,这点不用改 安装gdiplus插件,这个需要...

mcy247
2017/12/05
0
0

没有更多内容

加载失败,请刷新页面

加载更多

nginx学习笔记

中间件位于客户机/ 服务器的操作系统之上,管理计算机资源和网络通讯。 是连接两个独立应用程序或独立系统的软件。 web请求通过中间件可以直接调用操作系统,也可以经过中间件把请求分发到多...

码农实战
49分钟前
5
0
Spring Security 实战干货:玩转自定义登录

1. 前言 前面的关于 Spring Security 相关的文章只是一个预热。为了接下来更好的实战,如果你错过了请从 Spring Security 实战系列 开始。安全访问的第一步就是认证(Authentication),认证...

码农小胖哥
今天
8
0
JAVA 实现雪花算法生成唯一订单号工具类

import lombok.SneakyThrows;import lombok.extern.slf4j.Slf4j;import java.util.Calendar;/** * Default distributed primary key generator. * * <p> * Use snowflake......

huangkejie
昨天
11
0
PhotoShop 色调:RGB/CMYK 颜色模式

一·、 RGB : 三原色:红绿蓝 1.通道:通道中的红绿蓝通道分别对应的是红绿蓝三种原色(RGB)的显示范围 1.差值模式能模拟三种原色叠加之后的效果 2.添加-颜色曲线:调整图像RGB颜色----R色增强...

东方墨天
昨天
10
1
将博客搬至CSDN

将博客搬至CSDN

算法与编程之美
昨天
12
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部