×

Discussion Board

Results 1 to 8 of 8
  1. #1
    Registered User
    Join Date
    Sep 2008
    Posts
    22

    alpha blending with two CfbsBitmap buit from arrays : rendering errors

    Hi,

    I would like to create an image (not from a png file or mbm) with alpha blending enabled.
    To do that I would like to use BitBltMasked as the rendering method.

    To do so, I build an image from an UInt8 array which contains the color data and then another one, the mask, with alpha value for blending (so with format EGray256).

    In a previous post I succeeded to do so with a png file (the two CFbsBitmaps being created by CImageDecoder::FileNew() and a parameter which tells the method to create a mask).

    But here I'd like to to it "manually".

    Code:
    	// copying the buffer into bitmap
    	const TInt KSizeWidth = 30;
    	const TInt KSizeHeight = 30;
    	
    
    	TSize bitmapSize(KSizeWidth, KSizeHeight);
    	
            //build alpha array
    	TUint8  alphaArray [(KSizeWidth) * (KSizeHeight)];
    	for(int k = 0; k < KSizeWidth; k++){
    		for(int l = 0; l < KSizeHeight; l++){
    		
    			if(k<KSizeWidth/2 && l<KSizeHeight/2){
    				alphaArray[(k + l * (KSizeWidth))] = 200;
    			}else if(k>KSizeWidth/2 && l<KSizeHeight/2){
    				alphaArray[(k + l * (KSizeWidth))] = 100;
    			}else if(k<KSizeWidth/2 && l>KSizeHeight/2){
    				alphaArray[(k + l * (KSizeWidth))] = 50;
    			}else if(k>KSizeWidth/2 && l>KSizeHeight/2){
    				alphaArray[(k + l * (KSizeWidth))] = 255;
    			}
    		}
    	}
    	
            //put array in descriptor (-> why +1?? -> other wise it crashes, I don't know why, user panic 23, as if it was not declared big enough)
    	HBufC8 * tmpBuf = HBufC8::NewMaxL((KSizeWidth) * (KSizeHeight) +1 );
    		
    	tmpBuf->operator =(alphaArray);
    	
    	CFbsBitmap * iBitmapMask = new (ELeave) CFbsBitmap;
    	iBitmapMask->Create(bitmapSize, EGray256 );
    	iBitmapMask->LockHeap(ETrue);
    	Mem::Copy(iBitmapMask->DataAddress(), tmpBuf, tmpBuf->Length() -1 );
    	iBitmapMask->UnlockHeap(ETrue);
    	
    	delete tmpBuf;
    Okay I have more code for color image, but this one is already not working.
    So let's say I want to call BitBltMasked() with this bitmap for image and mask.

    I should see a semi transparent 30x30 square, with 4 quarters having different tone.

    What I see is a 30x30 square indeed, but the first 4 pixels (on the first line) are not set (as if iBitmapMask->DataAddress() didn't return a correct value... actually, I've tried to Mem::copy(iBitmapMask->DataAddress() - 1... and it worked ... But I don't know why, and it does not seem like something I should do)

    I also miss about 64 pixels at the end (they're white), as if there was not enough data in the array to fill the bitmap.

    And the 4 quarters are not correctly rendered, all lines seems shifted as if there was a pb with the TDisplayMode format...

    I really don't understand what I see , I believe this code should work (even without the +/-1 stuff), because I'm so close to getting what i'm expecting, there just a glitch in the rendering...

    And for the colored version, If I use the 32 bpp format EColor16MA I see the shape I draw alright, but with the true color 24 bpp format EColor16M, there the same pb of rendering, each line is shifted by one or two pixels, which deforms the image.

    (I'd rather like to use EColor16M, because with the second bitmap with alpha infos, using EColor16MA would be redondant, and increase memory footprint. But If it is the only one that's working, I'll take it ! ^^)

    Here's the code of the color array (EColor16MA version, for EColor16M, I only give 3 colors, and replace every 4 by 3 int the following code)

    Code:
    	TUint8 rgbArray [KSizeWidth * KSizeHeight * 4];
    	for(int i = 0; i < KSizeWidth *4 ; i+=4){
    		for(int j = 0; j < KSizeHeight ; j++){
    		
    			if(i<(KSizeWidth *4)/2 && j < KSizeHeight/2){
    				rgbArray[(i + j * KSizeWidth*4) + 0] = 200;
    				rgbArray[(i + j * KSizeWidth*4) + 1] = 20;
    				rgbArray[(i + j * KSizeWidth*4) + 2] = 20;
    				rgbArray[(i + j * KSizeWidth*4) + 3] = 20;
    			}else if(i>(KSizeWidth *4)/2 && j < KSizeHeight/2){
    				rgbArray[(i + j * KSizeWidth*4) + 0] = 20;
    				rgbArray[(i + j * KSizeWidth*4) + 1] = 200;
    				rgbArray[(i + j * KSizeWidth*4) + 2] = 20;
    				rgbArray[(i + j * KSizeWidth*4) + 3] = 20;
    			}else if(i<(KSizeWidth *4)/2 && j > KSizeHeight/2){
    				rgbArray[(i + j * KSizeWidth*4) + 0] = 20;
    				rgbArray[(i + j * KSizeWidth*4) + 1] = 20;
    				rgbArray[(i + j * KSizeWidth*4) + 2] = 200;
    				rgbArray[(i + j * KSizeWidth*4) + 3] = 20;
    			}else if(i>(KSizeWidth *4)/2 && j > KSizeHeight/2){
    				rgbArray[(i + j * KSizeWidth*4) + 0] = 20;
    				rgbArray[(i + j * KSizeWidth*4) + 1] = 200;
    				rgbArray[(i + j * KSizeWidth*4) + 2] = 200;
    				rgbArray[(i + j * KSizeWidth*4) + 3] = 20;
    			}
    		}
    	}
    Sorry for the huge message but I would like to be as precise as possible.
    Furthermore, I'd like someone to try this code to see if it gets the same result as I do, or tell me if there is something obviously wrong with it ...

    Thanks a lot!

  2. #2
    Nokia Developer Moderator
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    28,674

    Re: alpha blending with two CfbsBitmap buit from arrays : rendering errors

    That temporary descriptor ruins everything:
    - first of all it doubles memory usage for vain (you already have a fully functional array)
    - descriptors support usage of traditional 0-terminated strings (which are supposed to be text by the way), that is why operator=, Copy, and constructors accepting TUint8* exist - however in your case you have binary data, which is not explicitly 0-terminated
    - since you are extremely lucky, it still turns out to be 0-terminated anyway, that is why the "+1" is enough: your KSizeX-s are probably less than 256, so the 2nd byte of TSize bitmapsize variable is 0 (the first one probably stores the non-0 part of KSizeWidth) - this is why the +1 is "required"
    - HBufC is actually an object, not raw memory. Its first 4 bytes stores the length of the given object, then comes the data. That is why the first 4 pixels are not correct.

    What about
    Code:
    Mem::Copy(iBitmapMask->DataAddress(), alphaArray, (KSizeWidth) * (KSizeHeight));
    ?

  3. #3
    Registered User
    Join Date
    Sep 2008
    Posts
    22

    Re: alpha blending with two CfbsBitmap buit from arrays : rendering errors

    thanks for your answer!
    I'm glad to get rid of the descriptor ^^.

    It solved the problem of the first four pixels.
    EColor16MA gives me a correct result.
    But In the case of EGray256 and EColor16M, my shape is still drawn diagonally... And there is almost 2 lines at the bottom of my square that is white, as if my square bitmap lacked data. I'd like to attach a picture, it's not easy to describe, and it would give you a better idea of what's going on.

    here's the new piece of code, I've changed the value for the last(bottom left part) of the image from 255 to something lighter, so that the white lines at the end can not be confused with actual array data (I mean, they must represent a lack of data).

    Code:
    	// copying the buffer into bitmap
    	const TInt KSizeWidth = 30;
    	const TInt KSizeHeight = 30;
    	
    	//dataBuffer
    	TUint8  alphaArray [KSizeWidth * KSizeHeight];
    	
    	for(int k = 0; k < KSizeWidth; k++){
    		for(int l = 0; l < KSizeHeight; l++){
    		
    			if(k<KSizeWidth/2 && l<KSizeHeight/2){
    				alphaArray[(k + l * (KSizeWidth))] = 200;
    			}else if(k>KSizeWidth/2 && l<KSizeHeight/2){
    				alphaArray[(k + l * (KSizeWidth))] = 100;
    			}else if(k<KSizeWidth/2 && l>KSizeHeight/2){
    				alphaArray[(k + l * (KSizeWidth))] = 50;
    			}else if(k>KSizeWidth/2 && l>KSizeHeight/2){
    				alphaArray[(k + l * (KSizeWidth))] = 155;
    			}
    		}
    	}
    	
    	CFbsBitmap * iBitmapMask = new (ELeave) CFbsBitmap;
    	
            iBitmapMask->Create(bitmapSize, EGray256 );
    	
            iBitmapMask->LockHeap(ETrue);
    	Mem::Copy(iBitmapMask->DataAddress(), alphaArray, KSizeWidth * KSizeHeigh );
    	iBitmapMask->UnlockHeap(ETrue);
    Here, a vague idea of what the image looks like, hope it helps:
    Code:
    *****####
    ***####**
    *####****
    ###*****#
    %%%%%££££
    %%%££££%%
    %££££%%%%
    £££%%%%%#
    ......... <-- white line(s)

    instead of :

    Code:
    ****####
    ****####
    ****####
    ****####
    %%%%££££
    %%%%££££
    %%%%££££
    %%%%££££
    Last edited by jillemash; 2009-07-09 at 08:04. Reason: the "ascii image " looked bad once publish. added CODE tags

  4. #4
    Nokia Developer Moderator
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    28,674

    Re: alpha blending with two CfbsBitmap buit from arrays : rendering errors

    Something consumes less memory than you expect:
    - it can be the pixel, EColor16M probably uses 3 bytes per pixel (EColor16MU seems to be the one which adds a dummy padding byte - and EColor16MA obviously uses 4 bytes)
    - and it can be the length of the scanline too: check CFbsBitmap:: DataStride. If it is not 0, you will have to copy your bitmap line-by-line (and skip the padding - for the calculations you can use CFbsBitmap::ScanLineLength too)

  5. #5
    Registered User
    Join Date
    Sep 2008
    Posts
    22

    Re: alpha blending with two CfbsBitmap buit from arrays : rendering errors

    Okay, I've tried something intuitively, I've changed the width value from 30 to 32, and the shape is straight again. But now it appears that I forgot something in the description of the image I got :

    Code:
    ****####
    ****####
    ****####
    ****####
    %%%*****
    %%%*£££
    %%%*£££
    %%%*£££

  6. #6
    Registered User
    Join Date
    Sep 2008
    Posts
    22

    Re: alpha blending with two CfbsBitmap buit from arrays : rendering errors

    My datastride value is 32 and not 0.
    can you tell me what it means?
    Because I can not find this function in this site's library, is this something undocumented on purpose?

    According to your last post I should then make calls to Mem::copy() in a loop, for each line?
    Could you tell me how it should look?

    I'd go for something like :
    Code:
    Tint scanLgthNbBytes = iBitmapMask->ScanLineLength(width,EGray256);
    
    for(int i = 0; i < height ; i++){
        Mem::Copy(iBitmapMask->DataAddress() + i * scanLgthNbBytes 
                 , alphaArray + i * width //<- or another way, just gives te idea of taking a line in array
                 , KSizeWidth );
    }

  7. #7
    Nokia Developer Moderator
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    28,674

    Re: alpha blending with two CfbsBitmap buit from arrays : rendering errors

    Yes, that approach should work.

  8. #8
    Registered User
    Join Date
    Sep 2008
    Posts
    22

    Re: alpha blending with two CfbsBitmap buit from arrays : rendering errors

    YES! thanks, you so saved me !

    Finally here's the code that's working, for EColor16M.
    It is the most general case, so I hope it'll help people with the same problem I had.

    Important : earlier I forgot to divide by 4 the result of CFbsBitmap::ScanLineLength().
    I saw in documentation this result was DWORD aligned.

    Code:
    	CFbsBitmap * iBitmap = new (ELeave) CFbsBitmap;
    	
            iBitmap->Create(bitmapSize,EColor16M);
    
    	TInt scanLgthNbBytes = iBitmap->ScanLineLength(KSizeWidth, EColor16M)/4;
    
    	iBitmap->LockHeap(ETrue);
    	for(int i = 0; i < KSizeHeight ; i++){
    	    Mem::Copy(iBitmap->DataAddress() + i * scanLgthNbBytes
    	             , rgbArray + i * KSizeWidth*3 
    	             , KSizeWidth*3 );
    	}
    	iBitmap->UnlockHeap(ETrue);
    Note: KSizeWidth*3 because EColor16M is 3 bytes per pixel. See how I built the array.

    Thanks again for your time, wizard_hu_

Similar Threads

  1. Png image and alpha blending
    By jillemash in forum Symbian Media (Closed)
    Replies: 2
    Last Post: 2009-07-07, 07:45
  2. painting bitmap, linker errors
    By hotter in forum Symbian
    Replies: 4
    Last Post: 2007-04-23, 21:02
  3. Svg images, transparency and alpha blending
    By hubbabubba in forum Symbian
    Replies: 5
    Last Post: 2006-07-07, 12:32
  4. Alpha blending?
    By tombryntesen in forum Mobile Java Media (Graphics & Sounds)
    Replies: 4
    Last Post: 2003-10-23, 20:14
  5. Does 7650 support alpha blending?
    By dying in forum Mobile Java Media (Graphics & Sounds)
    Replies: 1
    Last Post: 2003-06-23, 08:35

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
×