Delphi 2010 新增功能之: TWICImage 类[1] - 方便的图像格式转换

时间:2022-04-30 04:56:05

2010-12-03 11:08:53|  分类: SQl+delphi |  标签: |字号 订阅

Graphics 单元新增了 TWICImage 类, 该类的功能源于新增的 Wincodec.pas 单元. , `* y0 a; E4 _7 l# H9 w' ~

" `1 |# U4 {$ @) Y2 |; I1 k7 Q  WIC(Windows Imaging Component) 是 Windows 为 Vista 和 WPF 提供的用于图像编码、解码的 COM 组件, 但在 XP 下也能使用它.
* l( T5 `  l+ C4 I8 @% o2 V 3 m! T' h' D( l' k
  WIC 支持的图像有 BMP、PNG、ICO、JPEG、GIF、TIFF、HDP(HDP 是微软随 Vista 推出的新的图像格式).
& B. c: p4 @1 ~1 a# t
! z9 o1 j( d$ Y( R  Wincodec 单元里的那些 API 函数还是挺繁琐的, 不过 TWICImage 可以非常方便地操作这些格式的图像.
6 R3 q# O4 P( k  Z( i/ l! S; j
0 O$ C4 }7 F+ ?  这样以后使用 jpg、gif、png 等图片时, 有 TWICImage 就够了! + |9 @& g! \  N, \, b
& L5 ?$ Z8 v& e0 V: n
  本例假定有这张图片存在: c:\temp\test.jpg, 然后把它转换为其他格式. ; Y5 p2 l( V+ `& A1 t2 }
- f% n! p, L# C% j+ U* c, _9 N
unit Unit1;  + T; R* a( i$ t0 z0 `
 
) C3 z( k- d( N4 f+ Ginterface  ; w5 G; G) |. P% B' w
  ! v- I! e2 Q+ |  S! x
uses  & A" z* x+ F! w  p9 s' a% g! A# W
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
! L* Z. R8 A7 L: V Dialogs, StdCtrls;  , |7 s' \% `" y
 
7 I0 c% E, N3 G) w5 f* dtype 
4 K; S7 Z& w; i- w- x' M TForm1 = class(TForm) 
- z: w+ @/ B3 [3 ^$ u& I  Button1: TButton; 
" X% E4 W' D2 }  e, m- k  procedure Button1Click(Sender: TObject); 
  S/ K' O# q( h. g7 m+ B* G end;  7 f" H6 q, d' e3 a+ y
 
3 E1 e0 |# ^) v9 D4 T* R, M' Svar 
7 t6 x7 g9 x6 K Form1: TForm1;  * t0 g: x1 B2 F+ _: ?
  * k- N, K2 j# x% v& R! u; i
implementation 
0 Q1 ~! m+ H# u5 u 
8 w, s% b' o7 N, T{$R *.dfm}   6 L& e  I6 F* }$ B6 M9 P2 i
 
. Z8 `' T7 D2 @" b# c2 O( }+ p) \procedure TForm1.Button1Click(Sender: TObject);  3 W3 e  R& R' L( ?$ s& `9 \
var  . ]6 {9 }3 |- G+ q) C
 WicImg: TWICImage; 
( U* ?! c8 R6 z% \begin  + P+ E6 n5 j3 X
 WicImg := TWICImage.Create;  2 u; f& O$ v9 c6 D3 I/ d
 WicImg.LoadFromFile('c:\temp\test.jpg');  8 P9 X: C- l5 n8 y% w
 
3 R9 ]" [5 }$ V1 j8 g" g {在窗体上预览图片} 
' R& u) e3 L4 a. O Canvas.Draw(0, 0, WicImg); 
  w. v' H. Q! E! X 
8 }9 }: o$ n, g/ n" F {转换为 png} 
& ]9 g4 _' |8 N+ K% k. r WicImg.ImageFormat := TWICImageFormat.wifPng; 
0 S! N7 @, g2 |, `6 q0 _6 X' o; Z/ t WicImg.SaveToFile('c:\temp\test.png');  # e" v- p. p: B4 D
  ) A* W0 V2 K: Y( k7 ]
 WicImg.Free; 
& y" b3 A; O8 E+ e% P: O+ e: A) Yend; 
* U1 s7 u8 l4 ~3 H* k, s$ {" ?  8 p9 V1 y3 {! z. c4 l$ W. b* K  Q
end. 
TWICImage 的大多功能都非常容易使用, 它最强大的功能是 ImagingFactory: IWICImagingFactory 属性, 这是个类工厂的接口.
) _: m6 A. q- I# Z/ Q7 f" q
6 [& u  J$ c# V9 {( `  所谓类工厂是 COM 里的概念, COM 通过类工厂可以自己实例化一些类, 实例化后我们只管使用就是.
+ K) A0 S: h8 Q' c7 m0 [% w/ T/ e
- L. x, f! `5 j7 k# @8 L  通过 TWICImage.ImagingFactory 获取类工厂后, 再调用 CreateBitmapFlipRotator 建立旋转变换接口(IWICBitmapFlipRotator). $ f1 _5 G, u8 ~& ^( ~% f

' r3 N6 B- v4 ?: h6 n  然后用 IWICBitmapFlipRotator.Initialize 执行变换, 再把变换后的数据赋给 TWICImage, 至此完成变换. - M. O5 K) t- M% G1 f
. N0 _$ z/ ?% z- P
//可以使用的变换方式有:  
, V7 `; `2 s* ^WICBitmapTransformRotate0       = 0;  - x: m) q, v$ o3 I
WICBitmapTransformRotate90      = $1;  / G+ ~: U" H3 P: A+ |5 A" I
WICBitmapTransformRotate180      = $2;  * L& j) h( B5 K3 m. h( m% {0 v
WICBitmapTransformRotate270      = $3;  9 i9 ?( Q! [1 R- K
WICBitmapTransformFlipHorizontal   = $8;  9 A( }+ |1 g& \. t1 p. @
WICBitmapTransformFlipVertical    = $10; 
. \& U% y  Q( N; E+ g7 s
& k6 @; T3 i; E& ?+ O  测试代码: % G# J% E7 T2 c
  Y8 t$ {! L/ x- N" ^
unit Unit1;  4 m2 w7 p3 v% J; ~
  9 ~7 X5 Z+ C) a" g; b* S& L
interface 
! I  A4 z% u7 t' q! j( j 
# R, J& m0 m2 ~/ H3 z' W7 u9 u$ Muses    p: M' b9 i# [# S
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  . o: z' |# ]/ q* ~; ?  g0 I, V
 Dialogs, StdCtrls;  8 b3 L, F8 I8 r! V+ W
  3 V4 n, n- }  y) @' l
type 
. U, w4 c, e" T, Y  O TForm1 = class(TForm) 
% {9 s" w4 V# z+ P  Button1: TButton;  ( S8 I5 T) f# P3 p" |- U
  Button2: TButton; 
( u5 a* U& A- c, z1 J  procedure Button1Click(Sender: TObject);  " D7 i( N, S6 c8 H& l- L& ?$ _
  procedure Button2Click(Sender: TObject); 
, ^- M* ?/ K& J7 h4 Z end;  ) N- @/ D* |9 O3 @5 S0 o
  & g- [4 o4 W( t
var  9 B( ]* R; {$ b9 t4 e7 R3 j: ?
 Form1: TForm1;  1 ?5 m! b  b" J' Q$ a# u+ S8 q
  ) p" e+ b, p% Y  R+ S
implementation  ; g: k4 U5 z# |3 G6 Z
  7 C3 U' z; t' e' d7 v
{$R *.dfm}  ' _4 D" X8 R+ ], k, j1 ^; u
  ! a% {. \! C! C3 J
uses Wincodec;    u  r$ ]# n% o; G" d
  " e+ {% p* u2 [  A, ?; Y
procedure TForm1.Button1Click(Sender: TObject); 
" W; f4 L& @2 e) M& O& F  r3 _6 P" nvar 
7 ^+ \6 E" Q+ q. \' f! K WicImg: TWICImage;  , ~7 [3 H7 {* g$ c
 Factory: IWICImagingFactory;    {类工厂接口} 
$ i! `% `6 k% D2 P$ D0 C5 x FlipRotator: IWICBitmapFlipRotator; {旋转变换接口}  9 [+ z+ H; U) h8 E
begin  ; }) s8 j# e, X. W: m/ s- M
 {先建立 TWICImage 类并载入图片} 
. r' A4 l; g. ~* ?9 r WicImg := TWICImage.Create; 
3 b; @$ R: X; q' `. I8 Y3 A, B2 | WicImg.LoadFromFile('c:\temp\test.jpg');  , X% V. N: X4 ^6 J
  0 l3 s; ]) V: T3 R" D2 q
 {获取类工厂接口}  $ V) P$ K& T# e* h. ]
 Factory := WicImg.ImagingFactory; 
- b+ E7 f' f0 D' V 
. M: P6 c: `/ y {让类工厂建立旋转变换接口}  ; v! V2 b+ Z. v
 Factory.CreateBitmapFlipRotator(FlipRotator);  ; m2 q6 f) h$ F* h$ a5 ?4 E6 G
 
8 H4 h: I8 [) f* A {执行旋转变换, 这里是旋转 90度角; 注意旋转后的数据在 FlipRotator}  6 z' d' _' V. f8 P, C( @9 F
 FlipRotator.Initialize(WicImg.Handle, WICBitmapTransformRotate90); 
7 `' O. \3 G4 _8 ^! y0 H6 ?! c  ; w8 q; l8 O& }' r; N
 {更新 TWICImage 中的图像} 
5 D* Q$ Q$ z4 q WicImg.Handle := IWicBitmap(FlipRotator);  7 @! o8 |: ?8 I
  + `& e! ]# w% d7 [
 {看看}  ; V+ N& I! t% d  C3 ~
 Canvas.Draw(0, 0, WicImg);  1 m  U9 Z& i9 @/ l7 ?1 c
 
1 v' O; R7 g4 w* N0 h {释放} 
% J" |3 v: D. v% c FlipRotator := nil; 
- [" k0 _1 L) d* ?; i9 y Factory := nil; 
* V3 u4 c3 t0 f! p( {' B WicImg.Free;  ' R8 H% L! b5 v( T
end;  2 z: l! N* D2 V+ V2 a* L3 z  N. X2 U6 w
 
, t. _$ l- B7 e" A4 U1 a, j//还是上面的程序, 给了些返回值的判断 
& n4 Q- n- Z& r5 P0 e8 V9 c- c+ rprocedure TForm1.Button2Click(Sender: TObject); 
5 k! t8 f8 E4 j# Z9 u; W% J  vvar 
9 `% v! H5 z% b% z" |4 d1 t WicImg: TWICImage;  # ?/ X6 Y$ i- Z& y: R1 n: G) E& d
 Factory: IWICImagingFactory; 
) ?$ T2 |  h, j; Y$ B FlipRotator: IWICBitmapFlipRotator;  ) h$ o  r* c" {4 D
 hr: HRESULT;  ; A- D2 K0 q5 A9 p4 C0 D$ t8 X
begin 
' C* W* t# `3 Q WicImg := TWICImage.Create; 
# Z. T0 O( w) ?( O! M' z! E" g WicImg.LoadFromFile('c:\temp\test.jpg');  : p  h) k  S* e$ E7 q0 k
 
0 c3 n+ X( O% M; } Factory := WicImg.ImagingFactory;  * L7 w& ?& A& D
 
. g& M$ C2 J9 v% q5 P hr := E_INVALIDARG; {先给个无效的返回值}  7 S) J& B/ s0 m
 hr := Factory.CreateBitmapFlipRotator(FlipRotator);  , o! x) g4 }+ F3 q6 N
  2 I. l3 K9 Q5 \. m" D
 if Succeeded(hr) then {如果上一个函数的返回值成功} 
) \7 d6 J3 u; @8 e* S  hr := FlipRotator.Initialize(WicImg.Handle, WICBitmapTransformFlipVertical); 
% d2 \8 J( A" n: H3 l  $ @* B6 p& \, l% E! Q) A% Q' g
 if Succeeded(hr) then  4 e, y! m. {  X2 Q9 M7 X4 a; ^
  WicImg.Handle := IWicBitmap(FlipRotator); 
5 C  P: V0 U! F  2 c  N/ N0 [; [' a
 Canvas.Draw(0, 0, WicImg);  * r2 r( g& D8 D" W- L- B8 V" b; _
  5 D) r' K* D/ f, s; {% [
 FlipRotator := nil; 
6 [, g  i8 O3 L( g Factory := nil; 
: n2 h; M; v9 W  f1 u WicImg.Free; 
' H/ a2 C0 A! h* t  V4 ]end; 
' V9 N! r& Q- O. O" }7 R  + K* j" J4 e- K+ c
end.