English 中文(简体)
Image format and unsigned char arrays
原标题:

I m developping imaging functions (yes I REALLY want to reinvent the wheel for various reasons).

I m copying bitmaps into unsigned char arrays but I m having some problem with byte size versus image pixel format.

for example a lot of images come as 24 bits per pixel for RGB representation so that s rather easy, every pixel has 3 unsigned chars (bytes) and everyone is happy

however sometimes the RGB has weirder types like 48 bits per pixel so 16 bits per color channel. Copying the whole image into the byte array works fine but its when I want to retrieve the data that things get blurry

Right now I have the following code to get a single pixel for grayscale images

unsigned char NImage::get_pixel(int i, int j)
   {
   return this->data[j * pitch + i];
   }

NImage::data is unsigned char array

This returns a single byte. How can I access my data array with different pixel formats?

最佳回答

You should do it like this:

unsigned short NImage::get_pixel(int i, int j)
   {
       int offset = 2 * (j * pitch + i);
      // image pixels are usually stored in big-endian format
      return data[offset]*256 + data[offset+1];
   }
问题回答

At 48 bits per pixel, with 16 bit per color, you can t return an 8 bit value, you must return a 16 bit short or unsigned short otherwise the data gets truncated.

You might try developing overloaded functions to handle this.

You have to know how big your pixels are.

If it s RGB then your 100x100 pixel image (say) will have 30,000 unsigned chars.

unsigned char NImage::get_red_component(int i, int j) 
{ 
    return this->data[3*(j * pitch + i)]; 
}

unsigned char NImage::get_green_component(int i, int j) 
{ 
    return this->data[3*(j * pitch + i) + 1]; 
}

unsigned char NImage::get_blue_component(int i, int j) 
{ 
    return this->data[3*(j * pitch + i) + 2]; 
}

Or for 48-bit RGB,

unsigned char NImage::get_red_MSB(int i, int j) 
{ 
    return this->data[6*(j * pitch + i)]; 
}

unsigned char NImage::get_red_LSB(int i, int j) 
{ 
    return this->data[6*(j * pitch + i) + 1]; 
}

... etc etc ...

What s the problem with 48bits per pixel? Simply read your data as uint16_t or unsigned short and you get the 16 bit extracted properly.

It gets worse for more complicated bit pattern, i.e. rgb565 where you ll need to extract data using bitmasks.





相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?

热门标签