gpt4 book ai didi

c++ - 未填充到 4 字节的 3 channel 图像重采样?

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:11:30 25 4
gpt4 key购买 nike

我发现了一种图像重采样算法,可以在缩小尺寸时生成非常漂亮的图像。它适用于填充为每个像素 4 个字节的 3 channel 图像。我要更改什么才能使它适用于未填充为每个 channel 4 个字节的图像?就像一个 jpeg 图片。目标图像是 4 字节填充的。另外,你会给这个算法起什么名字?

最初在这里找到:http://www.geisswerks.com/ryan/FAQS/resize.html

代码简化:

void Resize_HQ(unsigned char* src, int w1, int h1, unsigned char* dest, int w2, int h2)
{
// arbitrary resize.
unsigned int *dsrc = (unsigned int *)src;
unsigned int *ddest = (unsigned int *)dest;

bool bUpsampleX = (w1 < w2);
bool bUpsampleY = (h1 < h2);

// If too many input pixels map to one output pixel, our 32-bit accumulation values
// could overflow - so, if we have huge mappings like that, cut down the weights:
// 256 max color value
// *256 weight_x
// *256 weight_y
// *256 (16*16) maximum # of input pixels (x,y) - unless we cut the weights down...
int weight_shift = 0;
float source_texels_per_out_pixel = ( (w1/(float)w2 + 1)
* (h1/(float)h2 + 1)
);
float weight_per_pixel = source_texels_per_out_pixel * 256 * 256; //weight_x * weight_y
float accum_per_pixel = weight_per_pixel*256; //color value is 0-255
float weight_div = accum_per_pixel / 4294967000.0f;
if (weight_div > 1)
weight_shift = (int)ceilf( logf((float)weight_div)/logf(2.0f) );
weight_shift = min(15, weight_shift); // this could go to 15 and still be ok.

float fh = 256*h1/(float)h2;
float fw = 256*w1/(float)w2;

// FOR EVERY OUTPUT PIXEL
for (int y2=0; y2<h2; y2++)
{
// find the y-range of input pixels that will contribute:
int y1a = (int)((y2 )*fh);
int y1b = (int)((y2+1)*fh);
if (bUpsampleY) // map to same pixel -> we want to interpolate between two pixels!
y1b = y1a + 256;
y1b = min(y1b, 256*h1 - 1);
int y1c = y1a >> 8;
int y1d = y1b >> 8;

for (int x2=0; x2<w2; x2++)
{
// find the x-range of input pixels that will contribute:
int x1a = (int)((x2 )*fw);
int x1b = (int)((x2+1)*fw);
if (bUpsampleX) // map to same pixel -> we want to interpolate between two pixels!
x1b = x1a + 256;
x1b = min(x1b, 256*w1 - 1);
int x1c = x1a >> 8;
int x1d = x1b >> 8;

// ADD UP ALL INPUT PIXELS CONTRIBUTING TO THIS OUTPUT PIXEL:
unsigned int r=0, g=0, b=0, a=0;
for (int y=y1c; y<=y1d; y++)
{
unsigned int weight_y = 256;
if (y1c != y1d)
{
if (y==y1c)
weight_y = 256 - (y1a & 0xFF);
else if (y==y1d)
weight_y = (y1b & 0xFF);
}

unsigned int *dsrc2 = &dsrc[y*w1 + x1c];
for (int x=x1c; x<=x1d; x++)
{
unsigned int weight_x = 256;
if (x1c != x1d)
{
if (x==x1c)
weight_x = 256 - (x1a & 0xFF);
else if (x==x1d)
weight_x = (x1b & 0xFF);
}

unsigned int c = *dsrc2++;//dsrc[y*w1 + x];
unsigned int r_src = (c ) & 0xFF;
unsigned int g_src = (c>> 8) & 0xFF;
unsigned int b_src = (c>>16) & 0xFF;
unsigned int w = (weight_x * weight_y) >> weight_shift;
r += r_src * w;
g += g_src * w;
b += b_src * w;
a += w;
}
}

// write results
unsigned int c = ((r/a)) | ((g/a)<<8) | ((b/a)<<16);
*ddest++ = c;//ddest[y2*w2 + x2] = c;
}
}
}

我尝试改变:

unsigned int *dsrc2 = &dsrc[y*w1 + x1c];

收件人:

unsigned char *dsrc2 = (unsigned char *) &dsrc[y*w1 + x1c];

和:

unsigned int c = *dsrc2++;

收件人:

unsigned int c = *(unsigned int *)dsrc2;
dsrc2 += 3;

还是没用...:|

最佳答案

原始代码使用 3 个字节用于颜色,1 个字节用于 alpha 或填充,每个像素 4 个字节。它读取 32 位整数,并屏蔽掉颜色。您没有第 4 个字节,因此您需要更改内容以从无符号字符读取。

dsrcddest 更改为 unsigned char *dsrc2 的声明就变成了

unsigned char *dsrc2 = &dsrc[(y*w1 + x1c) * 3];

丢弃 unsigned int c(两个地方)。将 r_src 等替换为

                unsigned int r_src = *dsrc2++;
unsigned int g_src = *dsrc2++;
unsigned int b_src = *dsrc2++;

写入结果也必须一次一个字节

        *ddest++ = unsigned char(r / a);
*ddest++ = unsigned char(g / a);
*ddest++ = unsigned char(b / a);

关于c++ - 未填充到 4 字节的 3 channel 图像重采样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48255096/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com