【发布时间】:2013-07-11 01:04:42
【问题描述】:
将原始像素图减少到 50% 的值很容易。我只是在地图上滑动一个 2x2 的正方形,然后平均 4 个像素的 RGB 分量,如下所示:
img = XGetImage(d_remote,RootWindow(d_remote,0),0,0,attr.width,attr.height,XAllPlanes(),ZPixmap);
int i;
int j;
for(i=0;i<attr.height;i=i+2){
for(j=0;j<attr.width;j=j+2) {
unsigned long p1 = XGetPixel(img, j, i);
unsigned long p1R = p1 & 0x00ff0000;
unsigned long p1G = p1 & 0x0000ff00;
unsigned long p1B = p1 & 0x000000ff;
unsigned long p2 = XGetPixel(img, j+1, i);
unsigned long p2R = p2 & 0x00ff0000;
unsigned long p2G = p2 & 0x0000ff00;
unsigned long p2B = p2 & 0x000000ff;
unsigned long p3 = XGetPixel(img, j, i+1);
unsigned long p3R = p3 & 0x00ff0000;
unsigned long p3G = p3 & 0x0000ff00;
unsigned long p3B = p3 & 0x000000ff;
unsigned long p4 = XGetPixel(img, j+1, i+1);
unsigned long p4R = p4 & 0x00ff0000;
unsigned long p4G = p4 & 0x0000ff00;
unsigned long p4B = p4 & 0x000000ff;
unsigned long averageR = (p1R+p2R+p3R+p4R)/4 & 0x00ff0000;
unsigned long averageG = (p1G+p2G+p3G+p4G)/4 & 0x0000ff00;
unsigned long averageB = (p1B+p2B+p3B+p4B)/4 & 0x000000ff;
int average = averageR | averageG | averageB;
XPutPixel(newImg, j/2, i/2, average);
}
}
这将使 500x500 的像素图变成 250x250 的像素图。这是减少 50%。如果我想把它扩大 20% 怎么办?例如,我希望我的 500x500 图像变成 400x400?我可以滑动的最小正方形是 2x2。我不明白我怎么能得到一个不是 2 的完美幂的减少。
解决方案:
这怎么努力??我修改了一个脚本,我发现它可以在 XImages 上进行双线性插值。它应该适用于任何通用像素图。我确实发现代码很难看,因为我将图像视为二维数组。我不明白为什么所有图像代码都映射到一维数组。更难想象。这适用于任何调整大小。
void resize(XImage* input, XImage* output, int sourceWidth, int sourceHeight, int targetWidth, int targetHeight)
{
int a, b, c, d, x, y, index;
float x_ratio = ((float)(sourceWidth - 1)) / targetWidth;
float y_ratio = ((float)(sourceHeight - 1)) / targetHeight;
float x_diff, y_diff, blue, red, green ;
int offset = 0 ;
int i=0;
int j=0;
int* inputData = (int*)input->data;
int* outputData = (int*)output->data;
for (i = 0; i < targetHeight; i++)
{
for (j = 0; j < targetWidth; j++)
{
x = (int)(x_ratio * j) ;
y = (int)(y_ratio * i) ;
x_diff = (x_ratio * j) - x ;
y_diff = (y_ratio * i) - y ;
index = (y * sourceWidth + x) ;
a = inputData[index] ;
b = inputData[index + 1] ;
c = inputData[index + sourceWidth] ;
d = inputData[index + sourceWidth + 1] ;
// blue element
blue = (a&0xff)*(1-x_diff)*(1-y_diff) + (b&0xff)*(x_diff)*(1-y_diff) +
(c&0xff)*(y_diff)*(1-x_diff) + (d&0xff)*(x_diff*y_diff);
// green element
green = ((a>>8)&0xff)*(1-x_diff)*(1-y_diff) + ((b>>8)&0xff)*(x_diff)*(1-y_diff) +
((c>>8)&0xff)*(y_diff)*(1-x_diff) + ((d>>8)&0xff)*(x_diff*y_diff);
// red element
red = ((a>>16)&0xff)*(1-x_diff)*(1-y_diff) + ((b>>16)&0xff)*(x_diff)*(1-y_diff) +
((c>>16)&0xff)*(y_diff)*(1-x_diff) + ((d>>16)&0xff)*(x_diff*y_diff);
outputData[offset++] = (int)red << 16 | (int)green << 8 | (int)blue;
}
}
}
【问题讨论】:
-
“滑动”一个 1.25 x 1.25 的正方形。如果 1.25x1.25 的正方形与多个正方形重叠,请相应地权衡平均值,以假装您只看到 1.25x1.25 的区域。
-
是的,但我的 i 和 j 只能增加一个整数,我只能访问一个整数像素。
-
这就是加权平均值的用途 - 它让您“访问”像素的一小部分。
-
-1 这是您上一个问题的确切代码。
-
而不是增加 2(这是除法的结果:100/50)相对而言,如果你想使 20% (100/20 = 5) 增加 5受影响之间的像素,它们将受到它们与混合像素之间距离的一定百分比的影响.. 示例:像素 4 在 50:50 与像素 5 混合,像素 0 与像素 4 相差 4,因此像素 0 和3 将与相邻的 25(adjacent):75(0 和 3) 混合,如 100/4 = 25,对于 p1 和 p2,它们将保持原样.. 只是一个建议,尚未测试结果.
标签: c image image-processing bitmap x11