04-26-2010 05:15 PM
I am allowing the user to open a png file that I want to scale to fit a popupScreen.
If I insert the Bitmap "image" with some tranparent pixles, it looks fine, but it is too small or too large.
If I use the scaleInto command the resluting "ScaledBitmap" loses any transparent pixle information and sometimes the reulting image is even distorted somehow.
Anyone run into this before???
ScaledBitmap = new Bitmap(Width, Height);
image.scaleInto(ScaledBitmap, Bitmap.SCALE_TO_FIT, Bitmap.FILTER_LANCZOS);
BackgroundImageField = new BitmapField(ScaledBitmap, BitmapField.NON_FOCUSABLE);
04-26-2010 06:34 PM
I use scaleInto for transparent images and it works fine. What I think your problem might be is the "ScaledBitmap" does not have alpha. Try using createAlpha before calling scaleInto.
04-26-2010 09:04 PM
I believe I ran into something similar. When a new bitmap is created, it is not set to transparent by default. The 'createAlpha' method needs to be called, but the pixels of the bitmap seem to stay in the opaque state.
I solved the problem with the following modification:
ScaledBitmap = new Bitmap(Width, Height);
ScaledBitmap.createAlpha(Bitmap.ALPHA_BITDEPTH_8BP
int[] stripe=Vec.intArray(0,Width);
for (int y=Height-1;y>=0;y--) ScaledBitmap.setARGB(stripe,0,Width,0,y,Width,1);
image.scaleInto(ScaledBitmap, Bitmap.SCALE_TO_FIT, Bitmap.FILTER_LANCZOS);
BackgroundImageField = new BitmapField(ScaledBitmap, BitmapField.NON_FOCUSABLE);
It's a bit awkward. Maybe there's a better way, or maybe a revised version of the API will address it.
04-26-2010 09:05 PM
(where int[] stripe=Vec.intArray(0,Width); is equivalent to
int[] stripe=new int[Width]; for (int n=Width-1;n>=0;n--) stripe[n]=0![]()
04-26-2010 11:54 PM
Thank you both for your response. I really appreciate the help!
AClark_xyz, Thanks for taking the time to include some code too.
I am afraid I couldn't get it to compile though. It didn't like the intArray command line. I am working with 5.0 and I did a text search of the API Reference and I couldn't find "intArray". But I think I see what you are doing.
I do not completely understand the createAlpha command or the intArray command yet, but I think somehow createAlpha allows the Bitmap to use transparent pixels but it does not actually set the pixels to transparent (like having a background the image is placed on). The setARGB command sets all pixels to transparent so there is no background.
The stripe/intArray command looks like it is for holding one line of the Bitmap pixels for processing by the setARGBcommand.
Unfortunately, I have to put it up for the night and I am off tomorrow. But I think when I pick it back up I can get it working. I'll just have to rifle through the API Reference
Thanks again for your help!
04-27-2010 09:00 AM
aclark_xyz explained what the Vec.intArray function was in his second post.
Here is what I did and had work:
//Create the image and create a alpha channel Bitmap image = new Bitmap(Bitmap.ROWWISE_16BIT_COLOR, width, height); image.createAlpha(Bitmap.ALPHA_BITDEPTH_8BPP); //Erase everything there so it is completely blank and transparent int[] transparentImage = new int[width * height]; image.setARGB(transparentImage, 0, width, 0, 0, width, height); //Scale the alpha-image into image. image2scale.scaleInto(..., image, ...);
You don't need to create a function to zero out everything (including alpha) because when you create a new array it is automatically set to zero for each element.
Bitmaps do not include an alpha channel unless explicitly specified, that is what createAlpha does.
04-27-2010 12:12 PM
Allocating an array of size (width*height) works fine, but it is wasteful, which is important for a resource-constrained mobile device. Allocating a single row ("stripe") and poking it into the bitmap one line at a time is a reasonable compromise. The bitmap itself already has its own matrix of pixels, so the parameter data is simply copied, rather than re-owned.
04-27-2010 02:14 PM
Understandable but as long as you don't keep refrences too it it will simple be put in the heap and released when the function is done. It also gives the CPU more time to work (since it doesn't have to keep a loop going and reset the actual pixels in memory).
04-28-2010 03:55 PM
Thanks for the assitional code rcmaniac25. I really appreciate the help!
This is odd though! I got closer in that the transparent pixles seem to be translating now. But I am still getting some very strange problems. I think pictures will work best as it is hard to describe.
The Star gets many small white lines around the border. I do not know what is happending to the heart, but it looks like some sort of distored heart behind a heart that looks like it scaled OK and the tranparent pixles worked OK.
So close. As soon as I solve this I can release my application. But what is happening is completely beyond me. The problem with the Star seems completely diferent than the problem with the heart.
04-28-2010 04:07 PM
I'm afraid you're beyond my limited area of expertise... but if I were in your position, I would start by trying a different resizing filter (e.g. bilinear), just in case that has something to do with it. Then look into the properties of the underlying PNG files themselves: play around with them - try a version with a solid background, or make a version where the edge alpha values are abrupt rather than a smooth transition, etc, just to see how that correlates to the result quality.
Don't forget that the BlackBerry bitmaps are displayed in 16-bit colour, while the bitmaps themselves are 24-bits + alpha. Smooth colour blends are rendered less well on the device, though I can't see why that would create jagged white outlines.