位图书写对角线出来 [英] Bitmap Writing Coming Out Diagonally

查看:127
本文介绍了位图书写对角线出来的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的代码如下给我试图编写一个奇数大小的250x250像素的位图图像的问题。当我用3个区域均匀地写出它时,例如。 160x160一切都很好。我花了几个小时试图让250x250和其他奇怪的区域正确写入,但它们不会,图像是对角的,一半是错误的颜色位。

一只忙碌的猫http://oi40.tinypic.com/2zxuidw.jpg



pre $ int $ screen_save_part(string filename,unsigned x,unsigned y,unsigned w,unsigned h)//假定本地整数很少endian
{
unsigned sz = w * h;
FILE * bmp = fopen(filename.c_str(),wb);
if(!bmp)return -1;
fwrite(BM,2,1,bmp);

std :: vector< unsigned char> rgbdata(3 * SZ);
glReadPixels(x,window_get_region_height_scaled() - h-y,w,h,GL_BGR,GL_UNSIGNED_BYTE,& rgbdata [0]);
// glBindFramebuffer(GL_DRAW_FRAMEBUFFER,prevFbo);

sz<< = 2;
fwrite(& sz,4,1,bmp);
fwrite(\0\0\\\\\'\\\\\\\\\\\\\\\'),
fwrite(& w,4,1,bmp);
fwrite(& h,4,1,bmp);
fwrite(\ 1 \\\\\\\\\\\\\\\\\\\') \\0\0\0\0\0\0\0\0\0\0\0\0\0\" ,28,1,BMP); (w& 3){
w * = 3;


size_t pad = 3 - (w%3);
sz - = sz>> 2; (unsigned i = 0; i< = sz; i + = w){
fwrite(& rgbdata [0] + i,sizeof(char),w,bmp)

);
fwrite(\0\0\0,sizeof(char),pad,bmp);
}

} else {fwrite(& rgbdata [0],w * 3,h,bmp); }

fclose(bmp);
rgbdata.clear();
返回0;
}

好吧,但是我要开始把我的头发拉出来,从字面上看,所有距离我最近的东西都是for循环,没有任何填充,只添加了一行额外的空数据,但是在图像顶部1px扫描线上给了我一条黑线,但它没有伸展问题。

解决方案

您希望扫描线之间的跨度(以字节为单位)为DWORD倍数。你现在正在做的是完全基于像素的数量(至少 if(w& 3)分支表明这一点),而不是字节数 - 每-pixel。如果你有一个24-bpp的像素,我期望看到一个测试(w * 3)%4 。如果这个值是> 0 ,那么您需要添加很多字节(每条扫描线)以满足对齐。





尝试替换您的分支:
$ b

  if(w& 3){


$ / code $ / pre
$ b $ p

bpp image):

  int scanline_padding =(w * 3)%4; //这将是一个值0-3 

// DWORD对齐不满足,对于每个扫描线添加[scanline_padding]字节
if(scanline_padding> 0){
for(unsigned i = 0; i fwrite(& rgbdata [0] +(i * 3 * w),sizeof(char)* 3,w,bmp); //这里没什么特别的
fwrite(\0\0\0,scanline_padding,1,bmp); //现在为魔术
}
}

// DWORD对齐得到满足,所以我们可以一次写完所有东西
else {
fwrite(& rgbdata [0],w * 3,h,bmp);
}

这是未经测试的,但应该起作用,或者至少应该给你的一些大方向......

My code as follows is giving me issues trying to write a bitmap image with an odd size 250x250 pixels. When I write it with an evenly divisibly by 3 area, eg. 160x160 everything is fine. I have spent a few hours now trying to get the 250x250 and other odd area's to write correctly but they just won't, the image is diagonal and half of it with the wrong color bits.

a busy cat http://oi40.tinypic.com/2zxuidw.jpg

    int screen_save_part(string filename,unsigned x,unsigned y,unsigned w,unsigned h) //Assumes native integers are little endian
    {
        unsigned sz = w * h;
        FILE *bmp=fopen(filename.c_str(), "wb");
        if (!bmp) return -1;
        fwrite("BM", 2, 1, bmp);

        std::vector<unsigned char> rgbdata(3*sz);
        glReadPixels(x,window_get_region_height_scaled()-h-y,w,h,GL_BGR, GL_UNSIGNED_BYTE, &rgbdata[0]);
        //glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prevFbo);

        sz <<= 2;
        fwrite(&sz,4,1,bmp);
        fwrite("\0\0\0\0\x36\0\0\0\x28\0\0",12,1,bmp);
        fwrite(&w,4,1,bmp);
        fwrite(&h,4,1,bmp);
        fwrite("\1\0\x18\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",28,1,bmp);

        if (w & 3) {
            w *= 3;
            size_t pad = 3 - (w % 3);
            sz -= sz >> 2;

            for(unsigned i = 0; i <= sz; i += w) {
                fwrite(&rgbdata[0] + i,sizeof(char),w,bmp);
                fwrite("\0\0\0",sizeof(char),pad,bmp);
            }

        } else { fwrite(&rgbdata[0], w*3, h, bmp); }

        fclose(bmp);
        rgbdata.clear();
        return 0;
    }

Ok, but yah I am about to start pulling my hair out here I have gone through literally everything the closest I got was a for loop after that one without any padding and just added an extra row of null data but that gave me a black line on the very top 1px scanline of the image, but it had no stretching issue.

解决方案

You want the stride between scanlines (in terms of bytes) to be a DWORD multiple. What you are doing right now is based entirely on the number of pixels (at least the if (w & 3) branch suggests this) and not the number of bytes-per-pixel. I would expect to see a test for (w * 3) % 4 if you have a 24-bpp pixel. If this value is > 0, then you need to add that many bytes (per-scanline) to satisfy alignment.

Try replacing your branch:

if (w & 3) {
    ...
}

With something more along the lines of this (24-bpp image):

int scanline_padding = (w * 3) % 4; // This will be a value from 0-3

// DWORD alignment not satisfied, for each scanline add [scanline_padding] bytes
if (scanline_padding > 0) {
  for(unsigned i = 0; i < h; i++) {
    fwrite(&rgbdata[0] + (i * 3 * w),sizeof(char)*3,w,bmp); // Nothing special here
    fwrite("\0\0\0", scanline_padding, 1, bmp);             // Now for the magic
  }
}

// DWORD alignment was satisfied, so we can write the entire thing all at once
else {
  fwrite(&rgbdata[0], w*3, h, bmp);
}

This is untested, but should work, or should at least give you some general direction...

这篇关于位图书写对角线出来的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆