纯C图像缩放代码(二次线性插值)

 1 /**
 2  * @desc   二次线性插值公式
 3  *         P0  P2
 4  *         P1  P3
 5  *         
 6  *           pm0=(1-u)*(1-v);
 7  *           pm1=v*(1-u);
 8  *           pm2=u*(1-v);
 9  *           pm3=u*v;
10  *         
11  *         dst = P0*pm0 + P1*pm1 + P2*pm2 + P3*pm3;
12  * @param  pline1    原图像P0  P2
13  * @param  pline2    原图像P1  P3
14  * @param  channels  图像通道数,1=灰阶、3=RGB888彩色
15  * @param  u         
16  * @param  v         
17  * @return           目标像素值
18  * **/
19 unsigned char linearInterpolation(unsigned char* pline1, unsigned char* pline2, int channels,int u, int v){
20     int pm3 = u * v;
21     int pm2 = (u << 8) - pm3;
22     int pm1 = (v << 8) - pm3;
23     int pm0 = (1 << 16) - pm1 - pm2 - pm3;
24 
25     unsigned char result = (unsigned char)(((pm0*pline1[0] + pm2 * pline1[channels] + pm1 * pline2[0] + pm3* pline2[channels]) >> 16)&0xff);
26     
27     return result;
28 }
29 
30 /**
31  * @desc   二次线性插值图像缩放
32  * @param  psrc       原图像
33  * @param  sw         原图像宽度 
34  * @param  sh         原图像高度
35  * @param  channels   图像通道数,1=灰阶、3=RGB888彩色
36  * @param  pdst       缩放后图像
37  * @param  dw         缩放后图像宽度 
38  * @param  dh         缩放后图像高度
39  * **/
40 void zoomImg(unsigned char *psrc, int sw, int sh,int channels, unsigned char *pdst, int dw, int dh)
41 {
42     if (!psrc || !pdst) return;
43     if (sw <= 0 || sh <= 0 || dw <= 0 || dh <= 0) return;
44     if (channels != 1 && channels != 3) return;
45 
46     unsigned char *p = psrc,*q = pdst,*pt;
47     int srcBytesPerLine = sw * channels,dstBytesPerLine = dw * channels;
48     int srcy_16 = 0, v_8 = 0, srcx_16 = 0;
49     int stepw = (((sw - 1) << 16) / dw +1);
50     int steph = ((sh - 1) << 16) / dh + 1;
51     int stepc = ((channels - 1) << 16)/channels + 1;
52     int i, j, m;
53 
54     srcy_16 = 0;
55     for (j = 0; j < dh; j++)
56     {
57         v_8 = (srcy_16 & 0xFFFF) >> 8;
58         p = psrc + srcBytesPerLine * (srcy_16 >> 16);
59         srcx_16 = 0;
60         for (i = 0; i < dstBytesPerLine; i+=channels)
61         {
62             pt = &p[(srcx_16>>16)*channels];
63 
64             for (m = 0; m < channels; m++) {
65                 q[i+m] = linearInterpolation(&pt[m], &pt[m] + srcBytesPerLine, channels, (srcx_16 & 0xFFFF) >> 8, v_8);
66             }
67 
68             srcx_16 += stepw;
69         }
70         srcy_16 += steph;
71     
72         q += dstBytesPerLine;
73     }
74 }
原文地址:https://www.cnblogs.com/ybqjymy/p/14261915.html