Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在未填充到4字节的3通道上进行图像重采样?_C++_Image_Algorithm_Visual Studio_Image Resizing - Fatal编程技术网

C++ 在未填充到4字节的3通道上进行图像重采样?

C++ 在未填充到4字节的3通道上进行图像重采样?,c++,image,algorithm,visual-studio,image-resizing,C++,Image,Algorithm,Visual Studio,Image Resizing,我发现了一种图像重采样算法,在缩小尺寸时可以产生非常好的图像。它适用于3通道图像,每像素填充4字节。对于一个没有填充到每个通道4字节的图像,我应该做些什么更改才能使其正常工作?像jpeg图像。目标映像是4字节填充的。另外,你会给这个算法取什么名字 最初在这里发现: 简化代码: void Resize_HQ(unsigned char* src, int w1, int h1, unsigned char* dest, int w2, int h2) { // arbitrary resi

我发现了一种图像重采样算法,在缩小尺寸时可以产生非常好的图像。它适用于3通道图像,每像素填充4字节。对于一个没有填充到每个通道4字节的图像,我应该做些什么更改才能使其正常工作?像jpeg图像。目标映像是4字节填充的。另外,你会给这个算法取什么名字

最初在这里发现:

简化代码:

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;
        }
    }
}
致:

以及:

致:


还是没用…:|

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

dsrc
ddest
更改为
无符号字符*
。然后,
dsrc2
的声明变为

unsigned char *dsrc2 = &dsrc[(y*w1 + x1c) * 3];
扔掉
无符号int c
(两个位置)。将
r\u 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);

我认为您输入了一个错误,dsrc2也应该声明为unsigned char*。这样做之后,你的配方就起作用了。谢谢
unsigned int c = *(unsigned int *)dsrc2;
dsrc2 += 3;
unsigned char *dsrc2 = &dsrc[(y*w1 + x1c) * 3];
                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);