Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I have raw image data (may be .png, .jpg, ...) and I want it converted in Android without changing its pixel depth (bpp). In particular, when I load a grayscale (8 bpp) image that I want to use as alpha (glTexImage() with GL_ALPHA), it converts it to 16 bpp (presumably 5_6_5).

While I do have a plan B (actually, I'm probably on plan 'E' by now, this is really becoming annoying) I would really like to discover an easy way to do this using what is readily available in the API.

So far, I'm using BitmapFactory.decodeByteArray().

While I'm at it. I'm doing this from a native environment via JNI (passing the buffer in from C, and a new buffer back to C from Java). Any portable solution in C/C++ would be preferable, but I don't want to introduce anything that might break in future versions of Android, etc.

share|improve this question
    
I'm not sure about the results but you may try to convert all image files into a single format first. then it willl be easier to customize one loading library. –  Ali.S Jun 23 '11 at 11:07
    
I can circumvent the problem by "knowing" what the image is and how I want to interpret it. But if Android would just give me the image as it should be, I wouldn't have to. –  stephelton Jun 23 '11 at 19:11
add comment

2 Answers

up vote 2 down vote accepted

Note that since JPEG images use a Y or YUV colourspace they do not really have a pixel depth and thus there is no "right" depth for them. That said, you are correct in expecting a 8bpp grayscale image when decoding a monochrome JPEG.

I don't know of an available API to achieve what you are trying to do in an automatic way. However, you can ask for a specific depth using the BitmapFactory preferred options:

 BitmapFactory.Options opts = new BitmapFactory.Options();
 // This option is suitable for monochrome JPEGs:
 opts.inPreferredConfig = Bitmap.Config.ALPHA_8;
 // This option is suitable for 32-bit PNGs:
 opts.inPreferredConfig = Bitmap.Config.RGB_8888;

 bitmap = BitmapFactory.decodeByteArray(data, 0, len, opts);

This is still a hint for the decoder and does not guarantee that you will always get what you expect. I have additional suggestions:

  • embed your own versions of libPNG and/or libJPEG. I suggest trying libjpeg-turbo which allows to fine-tune the available colourspaces even more.
  • instead of using PNG or JPEG as your interchange format, use one or several texture compression formats suitable for your target devices; there are readily available tools to convert PNGs to ETC1, which is part of the OpenGL ES standard. Maybe add a layer of gzip on top of that.
  • do not hesitate to experiment and try generic compression methods: store your image just as you would upload it to the video card, and compress it using libgz or libbzip2. I have images that get significantly smaller using bzip2 on an uncompressed version than when crushing with pngcrush. That may be an acceptable tradeoff.

Hope this helps!

share|improve this answer
    
Thanks, these are all useful suggestions. I will consider them when I get back around to this issue; however, I am also considering adopting SDL, as it can help me keep my codebase very portable. –  stephelton Jun 29 '11 at 1:15
add comment

There is a question on StackOverflow that asks a similar question and there are a couple of solutions posted there. What have you tried so far?

share|improve this answer
    
That doesn't describe the same problem. The problem I'm having is that it's taking an 8bpp grayscale image and giving me a 16bpp rgb image. –  stephelton Jun 23 '11 at 19:09
    
The second post says the guy has a script that takes the image and builds the data into his code so you can load it into OpenGL directly in that format. –  CaseyB Jun 23 '11 at 19:17
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.