coreBugZJ

此 blog 已弃。

数字图像处理上机之二:图像放大缩小旋转和平移处理

 
1. 最邻近插值
对于通过反向变换得到的一个浮点坐标,对其进行简单的取整(或加上0.5后取整),得到一个整数型坐标,这个整数型坐标对应的像素值就是目的像素的像素值,最邻近插值简单且直观,运算速度快,但得到的图像质量不高。

2. 双线性插值
  对于一个目的像素,设坐标通过反向变换得到的浮点坐标为(i+u,j+v),其中i、j均为非负整数,u、v为[0,1)区间的浮点数,则这个像素得值 f(i+u,j+v) 可由原图像中坐标为 (i,j)、(i+1,j)、(i,j+1)、(i+1,j+1)所对应的周围四个像素的值决定,即
    f(i+u,j+v) = (1-u)(1-v)f(i,j) + (1-u)vf(i,j+1) + u(1-v)f(i+1,j) + uvf(i+1,j+1)
其中f(i,j)表示源图像(i,j)处的像素值,以此类推。
  双线性内插值法计算量大,但缩放后图像质量高,不会出现像素值不连续的的情况。由于双线性插值具有低通滤波器的性质,使高频分量受损,所以可能会使图像轮廓在一定程度上变得模糊。

3. 图像缩放
假设图像 x 轴方向缩放比例为 fx,y 轴方向缩放比例为 fy,则新图中的点(x,y)与原图中点(x0,y0)的转换关系为
x0 = x / fx,
y0 = y / fy,
即新图(x,y)处的像素就是原图(x0,y0)处的像素,但x0 与 y0 为浮点数,需使用插值算法,求出实际像素数据。

4. 图像旋转
先确定二维直角坐标系为 x 轴正方向向右,y 轴正方向向像下。绕原点旋转 a 弧度,逆时针方向 a 大于 0,顺时针方向 a 小于 0 。在原图和新图中都建立此坐标系,原点在图像中心。则原图中的点(x0,y0)旋转 a 弧度后,得到新图中的点(x1,y1):
x1 = cos(a) * x0 + sin(a) * y0
y1 = cos(a) * y0 – sin(a) * x0

实际旋转中要注意坐标系的转换。

求新图的大小,可以将原图中的四个角点,都旋转 a 弧度,得到新的四个点,在此四个点中找到最大最小的 x 及 y 坐标,从而求出新图大小。

5.图像平移
坐标平移一下即可,不再赘述。

6.界面
界面采用 MFC MDI 框架,使用菜单加对话框的交互方式,不太追求用户体验,只求展示原理。



插值算法独立为一个函数,内部又有其它函数调用,导致效率低。

所有图像处理算法,只针对 真彩色和灰度图,对于其它带调色板的图像,算法将其视为灰度图处理,故而结果不可预料。

当初为了可移植性,算法中所有浮点数操作及科学计算使用宏,以求在需要时自定义数据类型模拟浮点数,这导致代码繁琐。




界面




放大4倍最邻近插值




放大4倍双线性插值










1/*
2ProcessInterpolationZ.h
3
4Copyright (C) 2011, coreBugZJ, all rights reserved.
5
6图像插值算法。
7*/

8
9
10#ifndef __PROCESSINTERPOLATION_Z_H_INCLUDED__
11#define __PROCESSINTERPOLATION_Z_H_INCLUDED__
12
13
14#include "TypeZ.h"
15#include "ClassImageZ.h"
16
17
18/* 插值算法 */
19 /* 最邻近插值 Nearest Neighbor Interpolation */
20#define ITP_NEAREST_NEIGHBOR_Z 10
21 /* 双线性插值 Bilinear Interpolation */
22#define ITP_BILINEAR_Z 20
23
24
25 /* 为了效率 */
26 /* 只是简单的检查了指针是否为 NULL,未检查图像是否合法 */
27 /* 通过图像指针直接访问了图像数据 */
28 /* 最终还是调用了 ImageZ 的函数,导致效率不高 */
29PublicFuncZ R32 interpolateZ( cImageZ img, F64 fx, F64 fy, U32 itp, PixelZ *pixel );
30
31
32#endif /* __PROCESSINTERPOLATION_Z_H_INCLUDED__ */
33



1/*
2ProcessInterpolationZ.c
3
4Copyright (C) 2011, coreBugZJ, all rights reserved.
5
6图像插值算法。
7*/

8
9
10#include "stdafx.h"
11#include "ProcessInterpolationZ.h"
12
13
14PublicFuncZ R32 interpolateZ( cImageZ img, F64 fx, F64 fy, U32 itp, PixelZ *pixel ) {
15 I32 ix, iy;
16 U32 x, y;
17
18 if ( (NULL == img) || (NULL == pixel) ) {
19 return RERR;
20 }

21
22 MOV_I32_F64_Z(ix,fx);
23 if ( 0 > ix ) {
24 return RERR;
25 }

26 x = ix;
27 if ( x >= img->width ) {
28 return RERR;
29 }

30
31 MOV_I32_F64_Z(iy,fy);
32 if ( 0 > iy ) {
33 return RERR;
34 }

35 y = iy;
36 if ( y >= img->height ) {
37 return RERR;
38 }

39
40 switch ( itp ) {
41 case ITP_NEAREST_NEIGHBOR_Z :
42 return getImagePixelZ( img, x, y, pixel );
43
44 case ITP_BILINEAR_Z :
45 {
46 F64 nx, ny, dx, dy, t1, ts;
47 U32 x1, y1;
48 PixelZ p00, p01, p10, p11;
49 I32 ti;
50
51 MOV_F64_I32_Z(t1,((I32)1));
52
53 ix = x;
54 MOV_F64_I32_Z(nx,ix);
55 SUB_F64_Z(dx,fx,nx);
56 SUB_F64_Z(nx,t1,dx);
57
58 iy = y;
59 MOV_F64_I32_Z(ny,iy);
60 SUB_F64_Z(dy,fy,ny);
61 SUB_F64_Z(ny,t1,dy);
62
63 x1 = x + 1;
64 if ( x1 >= img->width ) {
65 x1 = img->width - 1;
66 }

67
68 y1 = y + 1;
69 if ( y1 >= img->height ) {
70 y1 = img->height - 1;
71 }

72
73 if ( ( ROK != getImagePixelZ( img, x, y, &p00 ) ) ||
74 ( ROK != getImagePixelZ( img, x, y1, &p01 ) ) ||
75 ( ROK != getImagePixelZ( img, x1, y, &p10 ) ) ||
76 ( ROK != getImagePixelZ( img, x1, y1, &p11 ) )
77 ) {
78 return RERR;
79 }

80
81#define BL_IN(uuu,xxx,yyy) do { \
82 ti = (uuu); \
83 MOV_F64_I32_Z(t1,ti); \
84 MUL_F64_Z(t1,t1,(xxx)); \
85 MUL_F64_Z(t1,t1,(yyy)); \
86 ADD_F64_Z(ts,ts,t1);\
87 }
while ( 0 )
88#define BL_HELP(us,u00,u01,u10,u11) do { \
89 MOV_F64_I32_Z(ts,((I32)0)); \
90 BL_IN( (u00), nx, ny ); \
91 BL_IN( (u01), nx, dy ); \
92 BL_IN( (u10), dx, ny ); \
93 BL_IN( (u11), dx, dy ); \
94 MOV_I32_F64_Z(ti,ts); \
95 (us) = (U08)ti; \
96 }
while ( 0 )
97
98 if ( isImagePaletteUsedZ(img) ) {
99 BL_HELP( pixel->index, p00.index, p01.index, p10.index, p11.index );
100 }

101 else {
102 BL_HELP( pixel->color.r, p00.color.r, p01.color.r, p10.color.r, p11.color.r );
103 BL_HELP( pixel->color.g, p00.color.g, p01.color.g, p10.color.g, p11.color.g );
104 BL_HELP( pixel->color.b, p00.color.b, p01.color.b, p10.color.b, p11.color.b );
105 BL_HELP( pixel->color.a, p00.color.a, p01.color.a, p10.color.a, p11.color.a );
106 }

107#undef BL_HELP
108#undef BL_IN
109 }
/* case */
110 return ROK;
111 }
112
113 return RERR;
114}
115



1/*
2ProcessGeometryZ.h
3
4Copyright (C) 2011, coreBugZJ, all rights reserved.
5
6几何变换(镜像,转置,扩大,剪裁,缩放,旋转等)。
7*/

8
9
10#ifndef __PROCESSGEOMETRY_Z_H_INCLUDED__
11#define __PROCESSGEOMETRY_Z_H_INCLUDED__
12
13
14#include "TypeZ.h"
15#include "ClassImageZ.h"
16
17
18 /* 镜像变换 */
19PublicFuncZ R32 mirrorImageZ( ImageZ img, B32 horz );
20PublicFuncZ ImageZ createImageMirrorZ( cImageZ src, B32 horz );
21 /* 转置 */
22PublicFuncZ ImageZ createImageTransposeZ( cImageZ src );
23PublicFuncZ R32 transposeImageZ( ImageZ img );
24 /* 扩张 */
25PublicFuncZ ImageZ createImageExpandZ( cImageZ src, U32 left, U32 top, U32 right, U32 bottom, const PixelZ *pBk );
26PublicFuncZ R32 expandImageZ( ImageZ img, U32 left, U32 top, U32 right, U32 bottom, const PixelZ *pBk );
27 /* 剪裁 */
28PublicFuncZ ImageZ createImageCropZ( cImageZ src, U32 left, U32 top, U32 width, U32 height );
29PublicFuncZ R32 cropImageZ( ImageZ img, U32 left, U32 top, U32 width, U32 height );
30 /* 缩放 */
31 /* 水平缩放为原来的 xf 倍 */
32 /* 垂直缩放为原来的 yf 倍 */
33PublicFuncZ ImageZ createImageZoomZ( cImageZ src, F64 xf, F64 yf, U32 itp );
34PublicFuncZ R32 zoomImageZ( ImageZ img, F64 xf, F64 yf, U32 itp );
35 /* 旋转 90 度,单位 角度 */
36 /* clockwise 为 TRUE 则顺时针旋转,FALSE 逆时针旋转 */
37PublicFuncZ ImageZ createImageRotate90degreeZ( cImageZ src, B32 clockwise );
38PublicFuncZ R32 rotateImage90degreeZ( ImageZ img, B32 clockwise );
39 /* 旋转任意角,单位 弧度 */
40 /* rad 若 > 0 则逆时针旋转,若 < 0 则顺时针旋转 */
41 /* 旋转之后会扩大图像,新区域填充 (*pBk) */
42PublicFuncZ ImageZ createImageRotateZ( cImageZ src, F64 rad, U32 itp, const PixelZ *pBk );
43PublicFuncZ R32 rotateImageZ( ImageZ img, F64 rad, U32 itp, const PixelZ *pBk );
44
45
46#endif /* __PROCESSGEOMETRY_Z_H_INCLUDED__ */
47



1/*
2ProcessGeometryZ.c
3
4Copyright (C) 2011, coreBugZJ, all rights reserved.
5
6几何变换(镜像,转置,扩大,剪裁,缩放,旋转等)。
7*/

8
9
10#include "stdafx.h"
11#include "ProcessGeometryZ.h"
12#include "ProcessInterpolationZ.h"
13#include "MathZ.h"
14
15
16PublicFuncZ R32 mirrorImageZ( ImageZ img, B32 horz ) {
17 U32 x0, x1, y0, y1, x, y, width, height;
18 PixelZ p0, p1;
19
20 if ( !isImageValidZ(img) ) {
21 return RERR;
22 }

23 width = getImageWidthZ( img );
24 height = getImageHeightZ( img );
25
26 if ( horz ) {
27 x0 = 0;
28 x1 = width - 1;
29 while ( x0 < x1 ) {
30 for( y = 0; y < height; ++y ) {
31 if ( (ROK != getImagePixelZ( img, x0, y, &p0 )) ||
32 (ROK != getImagePixelZ( img, x1, y, &p1 )) ||
33 (ROK != putImagePixelZ( img, x0, y, &p1 )) ||
34 (ROK != putImagePixelZ( img, x1, y, &p0 ))
35 ) {
36 return RERR;
37 }

38 }

39 ++x0;
40 --x1;
41 }

42 }

43 else {
44 y0 = 0;
45 y1 = height - 1;
46 while ( y0 < y1 ) {
47 for ( x = 0; x < width; ++x ) {
48 if ( (ROK != getImagePixelZ( img, x, y0, &p0 )) ||
49 (ROK != getImagePixelZ( img, x, y1, &p1 )) ||
50 (ROK != putImagePixelZ( img, x, y0, &p1 )) ||
51 (ROK != putImagePixelZ( img, x, y1, &p0 ))
52 ) {
53 return RERR;
54 }

55 }

56 ++y0;
57 --y1;
58 }

59 }

60
61 return ROK;
62}

63
64PublicFuncZ ImageZ createImageMirrorZ( cImageZ src, B32 horz ) {
65 ImageZ img = createImageFromImageZ( src );
66 if ( !isImageValidZ(img) ) {
67 return NULL;
68 }

69 if ( ROK != mirrorImageZ( img, horz ) ) {
70 destroyImageZ( img );
71 return NULL;
72 }

73 return img;
74}

75
76PublicFuncZ ImageZ createImageTransposeZ( cImageZ src ) {
77 U32 width, height, x, y;
78 ImageZ img;
79 PixelZ pixel;
80
81 if ( !isImageValidZ(src) ) {
82 return NULL;
83 }

84 width = getImageHeightZ( src );
85 height = getImageWidthZ( src );
86
87 img = createImageZ( width, height, getImageColorNumZ(src) );
88 if ( !isImageValidZ(img) ) {
89 return NULL;
90 }

91
92 if ( ROK != copyImagePaletteZ( img, src ) ) {
93 destroyImageZ( img );
94 return NULL;
95 }

96
97 for ( y = 0; y < height; ++y ) {
98 for ( x = 0; x < width; ++x ) {
99 if ( (ROK != getImagePixelZ( src, y, x, &pixel )) ||
100 (ROK != putImagePixelZ( img, x, y, &pixel ))
101 ) {
102 destroyImageZ( img );
103 return NULL;
104 }

105 }

106 }

107
108 return img;
109}

110
111PublicFuncZ R32 transposeImageZ( ImageZ img ) {
112 ImageZ tmp = createImageTransposeZ( img );
113 if ( !isImageValidZ(tmp) ) {
114 return RERR;
115 }

116 if ( ROK != swapImageZ( tmp, img ) ) {
117 destroyImageZ( tmp );
118 return RERR;
119 }

120 destroyImageZ( tmp );
121 return ROK;
122}

123
124PublicFuncZ ImageZ createImageExpandZ( cImageZ src, U32 left, U32 top, U32 right, U32 bottom, const PixelZ *pBk ) {
125 ImageZ img;
126 U32 width, height, colorNum, srcWidth, srcHeight;
127 U32 x, y;
128 PixelZ pixel;
129
130 if ( (!isImageValidZ(src)) || (pBk == NULL) ) {
131 return NULL;
132 }

133 colorNum = getImageColorNumZ( src );
134 srcWidth = getImageWidthZ( src );
135 srcHeight = getImageHeightZ( src );
136 width = srcWidth + left + right;
137 height = srcHeight + top + bottom;
138 if ( (colorNum > 0) && (pBk->index >= colorNum) ) {
139 return NULL;
140 }

141
142 img = createImageZ( width, height, colorNum );
143 if ( !isImageValidZ(img) ) {
144 return NULL;
145 }

146
147 if ( ROK != copyImagePaletteZ( img, src ) ) {
148 destroyImageZ( img );
149 return NULL;
150 }

151
152 for ( y = 0; y < srcHeight; ++y ) {
153 for ( x = 0; x < left; ++x ) {
154 if ( ROK != putImagePixelZ( img, x, top+y, pBk ) ) {
155 destroyImageZ( img );
156 return NULL;
157 }

158 }

159 for ( x = 0; x < srcWidth; ++x ) {
160 if ( (ROK != getImagePixelZ( src, x, y, &pixel )) ||
161 (ROK != putImagePixelZ( img, left+x, top+y, &pixel ))
162 ) {
163 destroyImageZ( img );
164 return NULL;
165 }

166 }

167 for ( x = 0; x < right; ++x ) {
168 if ( ROK != putImagePixelZ( img, left+srcWidth+x, top+y, pBk ) ) {
169 destroyImageZ( img );
170 return NULL;
171 }

172 }

173 }

174 for ( x = 0; x < width; ++x ) {
175 for ( y = 0; y < top; ++y ) {
176 if ( ROK != putImagePixelZ( img, x, y, pBk ) ) {
177 destroyImageZ( img );
178 return NULL;
179 }

180 }

181 for ( y = 0; y < bottom; ++y ) {
182 if ( ROK != putImagePixelZ( img, x, top+srcHeight+y, pBk ) ) {
183 destroyImageZ( img );
184 return NULL;
185 }

186 }

187 }

188
189 return img;
190}

191
192PublicFuncZ R32 expandImageZ( ImageZ img, U32 left, U32 top, U32 right, U32 bottom, const PixelZ *pBk ) {
193 ImageZ tmp = createImageExpandZ( img, left, top, right, bottom, pBk );
194 if ( !isImageValidZ(tmp) ) {
195 return RERR;
196 }

197 if ( ROK != swapImageZ( tmp, img ) ) {
198 destroyImageZ( tmp );
199 return RERR;
200 }

201 destroyImageZ( tmp );
202 return ROK;
203}

204
205PublicFuncZ ImageZ createImageCropZ( cImageZ src, U32 left, U32 top, U32 width, U32 height ) {
206 ImageZ img;
207 U32 srcWidth, srcHeight, colorNum, x, y;
208 PixelZ pixel;
209
210 if ( !isImageValidZ(src) ) {
211 return NULL;
212 }

213 srcWidth = getImageWidthZ( src );
214 srcHeight = getImageHeightZ( src );
215 colorNum = getImageColorNumZ( src );
216 if ( (left >= srcWidth) || (top >= srcHeight) ) {
217 return NULL;
218 }

219 if ( left + width > srcWidth ) {
220 width = srcWidth - left;
221 }

222 if ( top + height > srcHeight ) {
223 height = srcHeight - top;
224 }

225
226 img = createImageZ( width, height, colorNum );
227 if ( !isImageValidZ(img) ) {
228 return NULL;
229 }

230
231 if ( ROK != copyImagePaletteZ( img, src ) ) {
232 destroyImageZ( img );
233 return NULL;
234 }

235
236 for ( y = 0; y < height; ++y ) {
237 for ( x = 0; x < width; ++x ) {
238 if ( (ROK != getImagePixelZ( src, left+x, top+y, &pixel )) ||
239 (ROK != putImagePixelZ( img, x, y, &pixel ))
240 ) {
241 destroyImageZ( img );
242 return NULL;
243 }

244 }

245 }

246
247 return img;
248}

249
250PublicFuncZ R32 cropImageZ( ImageZ img, U32 left, U32 top, U32 width, U32 height ) {
251 ImageZ tmp = createImageCropZ( img, left, top, width, height );
252 if ( !isImageValidZ(tmp) ) {
253 return RERR;
254 }

255 if ( ROK != swapImageZ( tmp, img ) ) {
256 destroyImageZ( tmp );
257 return RERR;
258 }

259 destroyImageZ( tmp );
260 return ROK;
261}

262
263PublicFuncZ ImageZ createImageZoomZ( cImageZ src, F64 xf, F64 yf, U32 itp ) {
264 ImageZ img;
265 U32 srcWidth, srcHeight, colorNum, width, height;
266 U32 x, y;
267 PixelZ pixel;
268 F64 tf, fx, fy;
269
270 if ( !isImageValidZ(src) ) {
271 return NULL;
272 }

273 srcWidth = getImageWidthZ( src );
274 srcHeight = getImageHeightZ( src );
275 colorNum = getImageColorNumZ( src );
276
277 MOV_F64_U32_Z(tf,srcWidth);
278 MUL_F64_Z(tf,tf,xf);
279 MOV_U32_F64_Z(width,tf);
280 MOV_F64_U32_Z(tf,srcHeight);
281 MUL_F64_Z(tf,tf,yf);
282 MOV_U32_F64_Z(height,tf);
283
284 if ( (width < 1) || (height < 1) ) {
285 return NULL;
286 }

287
288 img = createImageZ( width, height, colorNum );
289 if ( !isImageValidZ(img) ) {
290 return NULL;
291 }

292
293 if ( ROK != copyImagePaletteZ( img, src ) ) {
294 destroyImageZ( img );
295 return NULL;
296 }

297
298 for ( y = 0; y < height; ++y ) {
299 MOV_F64_U32_Z(tf,y);
300 DIV_F64_Z(fy,tf,yf);
301 for ( x = 0; x < width; ++x ) {
302 MOV_F64_U32_Z(tf,x);
303 DIV_F64_Z(fx,tf,xf);
304 if ( (ROK != interpolateZ(src, fx, fy, itp, &pixel)) ||
305 (ROK != putImagePixelZ(img,x,y,&pixel))
306 ) {
307 destroyImageZ( img );
308 return NULL;
309 }

310 }

311 }

312
313 return img;
314}

315
316PublicFuncZ R32 zoomImageZ( ImageZ img, F64 xf, F64 yf, U32 itp ) {
317 ImageZ tmp = createImageZoomZ( img, xf, yf, itp );
318 if ( !isImageValidZ(tmp) ) {
319 return RERR;
320 }

321 if ( ROK != swapImageZ( tmp, img ) ) {
322 destroyImageZ( tmp );
323 return RERR;
324 }

325 destroyImageZ( tmp );
326 return ROK;
327}

328
329PublicFuncZ ImageZ createImageRotate90degreeZ( cImageZ src, B32 clockwise ) {
330 ImageZ img;
331 U32 width, height, colorNum, x, y;
332 PixelZ pixel;
333
334 if ( !isImageValidZ(src) ) {
335 return NULL;
336 }

337
338 width = getImageHeightZ( src );
339 height = getImageWidthZ( src );
340 colorNum = getImageColorNumZ( src );
341
342 img = createImageZ( width, height, colorNum );
343 if ( !isImageValidZ(img) ) {
344 return NULL;
345 }

346
347 if ( ROK != copyImagePaletteZ( img, src ) ) {
348 destroyImageZ( img );
349 return NULL;
350 }

351
352 if ( clockwise ) {
353 for ( y = 0; y < height; ++y ) {
354 for ( x = 0; x < width; ++x ) {
355 if ( (ROK != getImagePixelZ( src, y, width-1-x, &pixel )) ||
356 (ROK != putImagePixelZ( img, x, y, &pixel ))
357 ) {
358 destroyImageZ( img );
359 return NULL;
360 }

361 }

362 }

363 }

364 else {
365 for ( y = 0; y < height; ++y ) {
366 for ( x = 0; x < width; ++x ) {
367 if ( (ROK != getImagePixelZ( src, height-1-y, x, &pixel )) ||
368 (ROK != putImagePixelZ( img, x, y, &pixel ))
369 ) {
370 destroyImageZ( img );
371 return NULL;
372 }

373 }

374 }

375 }

376
377 return img;
378}

379
380PublicFuncZ R32 rotateImage90degreeZ( ImageZ img, B32 clockwise ) {
381 ImageZ tmp = createImageRotate90degreeZ( img, clockwise );
382 if ( !isImageValidZ(tmp) ) {
383 return RERR;
384 }

385 if ( ROK != swapImageZ( tmp, img ) ) {
386 destroyImageZ( tmp );
387 return RERR;
388 }

389 destroyImageZ( tmp );
390 return ROK;
391}

392
393PublicFuncZ ImageZ createImageRotateZ( cImageZ src, F64 rad, U32 itp, const PixelZ *pBk ) {
394 F64 fksin, fkcos, fi, fj, fx, fy, f1, f2;
395 U32 srcWidth, srcHeight, width, height, x, y, i;
396#define CORNER 4
397 F64 cnrX[ CORNER ], cnrY[ CORNER ], newX[ CORNER ], newY[ CORNER ];
398 F64 minX, minY, maxX, maxY;
399 ImageZ img;
400 PixelZ pixel;
401
402 if ( (!isImageValidZ(src)) || (NULL == pBk) ) {
403 return NULL;
404 }

405
406 srcWidth = getImageWidthZ( src );
407 MOV_F64_U32_Z( f1, srcWidth );
408 DIV_F64_U32_Z( f1, f1, 2 );
409 NEG_F64_Z( f2, f1 );
410 MOV_F64_Z( cnrX[ 0 ], f2 );
411 MOV_F64_Z( cnrX[ 1 ], f2 );
412 MOV_F64_Z( cnrX[ 2 ], f1 );
413 MOV_F64_Z( cnrX[ 3 ], f1 );
414
415 srcHeight = getImageHeightZ( src );
416 MOV_F64_U32_Z( f1, srcHeight );
417 DIV_F64_U32_Z( f1, f1, 2 );
418 NEG_F64_Z( f2, f1 );
419 MOV_F64_Z( cnrY[ 0 ], f2 );
420 MOV_F64_Z( cnrY[ 1 ], f1 );
421 MOV_F64_Z( cnrY[ 2 ], f1 );
422 MOV_F64_Z( cnrY[ 3 ], f2 );
423
424 SIN_F64_Z( fksin, rad );
425 COS_F64_Z( fkcos, rad );
426
427 /* fz = fa * fb + fc * fd */
428#define HELP_ADD( fz, fa, fb, fc, fd ) do { \
429 MUL_F64_Z( f1, (fa), (fb) ); \
430 MUL_F64_Z( f2, (fc), (fd) ); \
431 ADD_F64_Z( (fz), f1, f2 ); \
432 }
while ( 0 )
433 /* fz = fa * fb - fc * fd */
434#define HELP_SUB( fz, fa, fb, fc, fd ) do { \
435 MUL_F64_Z( f1, (fa), (fb) ); \
436 MUL_F64_Z( f2, (fc), (fd) ); \
437 SUB_F64_Z( (fz), f1, f2 ); \
438 } while ( 0 )
439 /* fz = max( fa, fb, fc, fd ) */
440#define HELP_MAX( fz, fa, fb, fc, fd ) do { \
441 MAX_F64_Z( f1, (fa), (fb) ); \
442 MAX_F64_Z( f2, (fc), (fd) ); \
443 MAX_F64_Z( (fz), f1, f2 ); \
444 } while ( 0 )
445 /* fz = min( fa, fb, fc, fd ) */
446#define HELP_MIN( fz, fa, fb, fc, fd ) do { \
447 MIN_F64_Z( f1, (fa), (fb) ); \
448 MIN_F64_Z( f2, (fc), (fd) ); \
449 MIN_F64_Z( (fz), f1, f2 ); \
450 } while ( 0 )
451
452 for ( i = 0; i < CORNER; ++i ) {
453 HELP_ADD( newX[ i ], fkcos, cnrX[ i ], fksin, cnrY[ i ] );
454 HELP_SUB( newY[ i ], fkcos, cnrY[ i ], fksin, cnrX[ i ] );
455 }

456
457 HELP_MAX( maxX, newX[ 0 ], newX[ 1 ], newX[ 2 ], newX[ 3 ] );
458 HELP_MIN( minX, newX[ 0 ], newX[ 1 ], newX[ 2 ], newX[ 3 ] );
459 HELP_MAX( maxY, newY[ 0 ], newY[ 1 ], newY[ 2 ], newY[ 3 ] );
460 HELP_MIN( minY, newY[ 0 ], newY[ 1 ], newY[ 2 ], newY[ 3 ] );
461
462 SUB_F64_Z( f1, maxX, minX );
463 MOV_U32_F64_Z( width, f1 );
464 SUB_F64_Z( f2, maxY, minY );
465 MOV_U32_F64_Z( height, f2 );
466
467 img = createImageZ( width, height, getImageColorNumZ(src) );
468 if ( !isImageValidZ( img ) ) {
469 return NULL;
470 }

471 if ( ROK != copyImagePaletteZ( img, src ) ) {
472 destroyImageZ( img );
473 return NULL;
474 }

475
476 for ( y = 0; y < height; ++y ) {
477 ADD_F64_U32_Z( fy, minY, y );
478 for ( x = 0; x < width; ++x ) {
479 ADD_F64_U32_Z( fx, minX, x );
480 HELP_SUB( fi, fkcos, fx, fksin, fy );
481 HELP_ADD( fj, fksin, fx, fkcos, fy );
482 ADD_F64_Z( fi, fi, cnrX[ 2 ] );
483 ADD_F64_Z( fj, fj, cnrY[ 2 ] );
484 if ( ROK == interpolateZ( src, fi, fj, itp, &pixel ) ) {
485 putImagePixelZ( img, x, y, &pixel );
486 }

487 else {
488 putImagePixelZ( img, x, y, pBk );
489 }

490 }

491 }

492
493#undef HELP_MIN
494#undef HELP_MAX
495#undef HELP_SUB
496#undef HELP_ADD
497#undef CORNER
498
499 return img;
500}
501
502PublicFuncZ R32 rotateImageZ( ImageZ img, F64 rad, U32 itp, const PixelZ *pBk ) {
503 ImageZ tmp = createImageRotateZ( img, rad, itp, pBk );
504 if ( !isImageValidZ(tmp) ) {
505 return RERR;
506 }

507 if ( ROK != swapImageZ( tmp, img ) ) {
508 destroyImageZ( tmp );
509 return RERR;
510 }

511 destroyImageZ( tmp );
512 return ROK;
513}

514













posted on 2011-11-08 22:07 coreBugZJ 阅读(1613) 评论(0)  编辑 收藏 引用 所属分类: VideoImage课内作业


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理