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

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 V3 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.