×

Discussion Board

Page 1 of 2 12 LastLast
Results 1 to 15 of 22
  1. #1
    Regular Contributor
    Join Date
    Sep 2009
    Posts
    285

    Inverting a bitmap and storing image

    Hello,

    I'm trying to write a code that reads an image (RGB or any format) and inverts the image. I did the reading part fine (I think) and now have a bitmap with the image.

    Hence, to invert the image, I need to do something like
    Code:
    bmp[x][y][i] = 255 - bmp[x][y][i]
    How can I access the individual elements in the bitmap?

    So far, this is how my code is:
    Code:
    int inv()
    	{
    	int wi, he, i, j;
    	RFs fs;
    	TRequestStatus as;	
    	CFbsBitmap* iB = new (ELeave) CFbsBitmap();
    	TRgb pix;
    	
    	CImageDecoder* idec = CImageDecoder::FileNewL(fs,_L("d:\\mordor\\logo.jpg"),_L8("image/jpeg"),CImageDecoder::EOptionAlwaysThread);
    	
    	iB->Create(idec->FrameInfo(0).iOverallSizeInPixels, idec->FrameInfo(0).iFrameDisplayMode );
    	TUint32* pxl = iB->DataAddress();
    	for (j=0; j<he; j++)
    		{
    		for (i=0; i<wi; i++)
    			{
    			*(pxl+j*wi+i) = 255 - *(pxl+j*wi+i);
    			}
    		}
    	
    	idec->Convert( &as, *iB );	
        User::WaitForRequest( as );
        
    	TBitmapUtil *bmp = new (ELeave) TBitmapUtil(iB);
    	
    	wi = int(iB->SizeInPixels().iWidth);
    	he = int(iB->SizeInPixels().iHeight);
    	
    	/******** NO IDEA HOW TO SAVE BITMAP TO NEW FILE ***********/
    	return 1;
    	}
    In the above, I expect the variable bmp to contain the bitmap of my required image. How can I access the individual pixels of the bitmap? Is the above mentioned inverting method correct?

    Also, considering I have the new bitmap (bmp_inv), how should I store it to a new jpg file (called "new.jpg", say)?
    Without knowing how to store the new bitmap into a file, I have no clue if the operation I have done is correct or not!
    I did find this class and I copied the .cpp and .h files to my src and inc folders (respectively). However, I do not know how to call the image. I tried:
    Code:
    MImageSavedCallBack& aCallBack;
    CJpgSaver::NewL(bmp,_L("d:\\mordor\\logo2.jpg"),MImageSavedCallBack& aCallBack);
    But that did not seem to work. Any idea how to call the function?


    Thanks
    Kedar
    Last edited by kedarm; 2010-03-05 at 14:21.

  2. #2
    Regular Contributor
    Join Date
    Sep 2009
    Posts
    285

    Re: Inverting a bitmap and storing image

    Could someone help out please?

    I've no clue how to go about this..

  3. #3
    Regular Contributor
    Join Date
    Apr 2008
    Location
    India
    Posts
    477

    Re: Inverting a bitmap and storing image

    For inversion:

    use TBitmapUtils (which u are using).

    and to store the bitmap:

    Just create the new bitmap of same size and while inverting save the pixel info in new bitmap


    Code will look like below:

    1. convert the jpg to bitmap
    2. create new bitmap of same size and same mode
    3. read the pixel info from the original bitmap from top left to right bottom and store in new bitmmap from right bottom to top left.
    Most human beings have an almost infinite capacity for taking things for granted.
    - Aldous Huxley

  4. #4
    Regular Contributor
    Join Date
    Sep 2009
    Posts
    285

    Re: Inverting a bitmap and storing image

    Quote Originally Posted by pawan_G View Post
    For inversion:
    use TBitmapUtils (which u are using).
    and to store the bitmap:
    Just create the new bitmap of same size and while inverting save the pixel info in new bitmap
    In the code I had given, doesn't the nested for loop do the inverting of the bitmap?
    Then, I create a new bitmap using TBitmapUtils.

    Quote Originally Posted by pawan_G View Post
    Code will look like below:
    1. convert the jpg to bitmap
    2. create new bitmap of same size and same mode
    3. read the pixel info from the original bitmap from top left to right bottom and store in new bitmmap from right bottom to top left.
    So, I think I figured out the first two steps. How do I save the bitmap that I now have?

  5. #5
    Regular Contributor
    Join Date
    Apr 2008
    Location
    India
    Posts
    477

    Re: Inverting a bitmap and storing image

    Quote Originally Posted by kedarm View Post
    Hello,

    I'm trying to write a code that reads an image (RGB or any format) and inverts the image. I did the reading part fine (I think) and now have a bitmap with the image.

    Hence, to invert the image, I need to do something like
    Code:
    bmp[x][y][i] = 255 - bmp[x][y][i]
    How can I access the individual elements in the bitmap?

    So far, this is how my code is:
    Code:
    int inv()
    	{
    	int wi, he, i, j;
    	RFs fs;
    	TRequestStatus as;	
    	CFbsBitmap* iB = new (ELeave) CFbsBitmap();
    	TRgb pix;
    	
    	CImageDecoder* idec = CImageDecoder::FileNewL(fs,_L("d:\\mordor\\logo.jpg"),_L8("image/jpeg"),CImageDecoder::EOptionAlwaysThread);
    	
    	iB->Create(idec->FrameInfo(0).iOverallSizeInPixels, idec->FrameInfo(0).iFrameDisplayMode );
    	TUint32* pxl = iB->DataAddress();
    	for (j=0; j<he; j++)
    		{
    		for (i=0; i<wi; i++)
    			{
    			*(pxl+j*wi+i) = 255 - *(pxl+j*wi+i);
    			}
    		}
    	
    	idec->Convert( &as, *iB );	
        User::WaitForRequest( as );
        
    	TBitmapUtil *bmp = new (ELeave) TBitmapUtil(iB);
    	
    	wi = int(iB->SizeInPixels().iWidth);
    	he = int(iB->SizeInPixels().iHeight);
    	
    	/******** NO IDEA HOW TO SAVE BITMAP TO NEW FILE ***********/
    	return 1;
    	}
    In the above, I expect the variable bmp to contain the bitmap of my required image. How can I access the individual pixels of the bitmap? Is the above mentioned inverting method correct?

    Also, considering I have the new bitmap (bmp_inv), how should I store it to a new jpg file (called "new.jpg", say)?
    Without knowing how to store the new bitmap into a file, I have no clue if the operation I have done is correct or not!
    I did find this class and I copied the .cpp and .h files to my src and inc folders (respectively). However, I do not know how to call the image. I tried:
    Code:
    MImageSavedCallBack& aCallBack;
    CJpgSaver::NewL(bmp,_L("d:\\mordor\\logo2.jpg"),MImageSavedCallBack& aCallBack);
    But that did not seem to work. Any idea how to call the function?


    Thanks
    Kedar

    Hope this will help
    Code:
    bitmap1-> original bitmap
    bitmap2-> new bitmap after inversion (create it with the same size and mode as bitmap1)
    
    TBitmapUtil utils1(bitmap1);
    TBitmapUtil utils2(bitmap2);
    utils1.Begin(TPoint(0,0));
    utils1.Begin(TPoint(bitmapwidth,bitmapheight));
    
    for(TInt i=0; i<bitmap1->SizeInPixels().iHeight;i++)
    {
    for(TInt j=0; i<bitmap1->SizeInPixels().iWidth;j++)
    {
    Utils2.SetPixel(utils1.GetPixel());
    Utils2.DecXPos();
    Utils1.IncXPos();
    }
    Utils1.IncYPos();
    Utils2.DecYPos();
    }
    Utils1.End();
    Utils2.End();
    Most human beings have an almost infinite capacity for taking things for granted.
    - Aldous Huxley

  6. #6
    Regular Contributor
    Join Date
    Sep 2009
    Posts
    285

    Re: Inverting a bitmap and storing image

    Hi!

    I tried the following -
    Code:
    	CImageDecoder* idec = CImageDecoder::FileNewL(fs,_L("c:\\logo.jpg"),_L8("image/jpeg"),CImageDecoder::EOptionAlwaysThread);
    	iB->Create(idec->FrameInfo(0).iOverallSizeInPixels, idec->FrameInfo(0).iFrameDisplayMode );
    	wi = int(iB->SizeInPixels().iWidth);
    	he = int(iB->SizeInPixels().iHeight);
    	FILE *f1 = fopen("c:\\data\\red.pgm","w");
    	FILE *f2 = fopen("c:\\data\\green.pgm","w");
    	FILE *f3 = fopen("c:\\data\\blue.pgm","w");
    	fprintf(f1,"P2\n%d %d\n255\n",wi,he);
    	fprintf(f2,"P2\n%d %d\n255\n",wi,he);
    	fprintf(f3,"P2\n%d %d\n255\n",wi,he);
    	iB->LockHeap();
    	TUint8* source = (TUint8*) iB->DataAddress();
    	for (i=0; i<he*wi; i++)
    		{
    		pxl[0] = (int) source[0];
    		pxl[1] = (int) source[1];
    		pxl[2] = (int) source[2];
    		fprintf(f1,"%d\n",pxl[0]);
    		fprintf(f2,"%d\n",pxl[1]);
    		fprintf(f3,"%d\n",pxl[2]);
    		source = source + 4;
    		}
    	iB->UnlockHeap();
    	fclose(f1);
    	fclose(f2);
    	fclose(f3);
    I want a simple code that can just read the bitmap of an image (logo.jpg) and write a pgm file of its channels (red, green and blue). However, when I run the code in the emulator, the pgm images I get (red.pgm, green.pgm and blue.pgm) are not the same as logo.jpg. They don't seem random, but they are incorrect.

    Any idea what I am doing wrong? I've gone through the code many times but can't figure out. The eventual aim is to invert the bitmap and store it.

    Thanks
    Kedar

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

    Re: Inverting a bitmap and storing image

    Consider checking CImageDecoder-examples in the Wiki once more. Your code creates the decoder object, and creates a bitmap. But it does not decode the image into that bitmap.

  8. #8
    Regular Contributor
    Join Date
    Sep 2009
    Posts
    285

    Re: Inverting a bitmap and storing image

    Hi Wizard_Hu_,

    thanks for the reply. I modified the code and added the following line -
    Code:
    idec->Convert(&as,*iB);
    Thus, the decoder object (idec) should decode the object (logo.jpg) into the bitmap (iB), right?

    My code now looks like this -
    Code:
    	CImageDecoder* idec = CImageDecoder::FileNewL(fs,_L("d:\\logo.jpg"),_L8("image/jpeg"),CImageDecoder::EOptionAlwaysThread);
    	iB->Create(idec->FrameInfo(0).iOverallSizeInPixels, idec->FrameInfo(0).iFrameDisplayMode );
    	idec->Convert(&as,*iB);
    However, when I proceed with the rest of my code, and create the bitmap files (.pgm files), I now get all pixel values to be '255'!

    I guess the problem lies with the fact that the decoding is an asynchronous call. I tried adding a "User::WaitForRequest( as );" after the Convert command, but it still does not get any better. Now, I get bitmap images that seem to be some garbage values.

    I tried calling 'SetActive' like is says here, but I get an error that says -
    undefined identifier 'SetActive'
    I tried searching for some examples that, but I couldn't follow them very well. Could you suggest some wiki page I could read that would explain how to read the bitmap?

    thanks
    kedar
    Last edited by kedarm; 2010-03-26 at 11:24.

  9. #9
    Regular Contributor
    Join Date
    Sep 2009
    Posts
    285

    Re: Inverting a bitmap and storing image

    Hi Wizard_Hu_,

    Sorry - it looks like there was some problem with my code. When I added the lines -
    Code:
    	TRequestStatus as;	
    	idec->Convert(&as,*iB);
    	User::WaitForRequest( as );
    after creating the CFbsBitmap, it seems to be working. I get a blurred image of the one I load.

    It looks like the problem is in accessing the pixels. Right now, I access the pixels in the following way -
    Code:
    	iB->LockHeap();
    	TUint8* source = (TUint8*) iB->DataAddress();
    	for (i=0; i<pixels; i++)
    		{
    		fprintf(f1,"%d\n",source[0]);
    		fprintf(f2,"%d\n",source[1]);
    		fprintf(f3,"%d\n",source[2]);
    		fprintf(f4,"%d\n",source[3]);
    		source = source + 4;
    		}
    	iB->UnlockHeap();
    How are the pixel values stored at the iB->DataAdress() location?

    My code assumes that the pixels are stored as 32 bit integers, divided into 4 channels of 8 bits each. Hence, for the 32 bit pixel ->
    bits 00 to 07 : value of red channel
    bits 08 to 15 : value of green channel
    bits 16 to 23 : value of blue channel
    bits 24 to 31 : <not sure what these correspond to>

    The above seems to be clearly wrong. Any idea how I can access the individual channels of the pixel?

    Please help!
    Thanks
    Kedar

  10. #10
    Nokia Developer Moderator
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    28,567

    Re: Inverting a bitmap and storing image

    Check what "idec->FrameInfo(0).iFrameDisplayMode" actually returns. If it is EColor16MU (or EColor16MA, though that is unlikely) your code should really access some channels (though they order may be different).
    TBitmapUtil is still an option, but its performance is slightly lower than direct reads from the memory.

  11. #11
    Regular Contributor
    Join Date
    Sep 2009
    Posts
    285

    Re: Inverting a bitmap and storing image

    Hi!

    I figured the previous problem out. I did not realize that it was a 3-channel image (RGB). Hence, the way I was accessing the pixels was wrong. I got that corrected.

    After doing all the changes, I wanted to save the CFbsBitmap (the variable is called 'iBitmap'). I tried the following command (from the SDK)-
    Code:
    iBitmap->Save(_L("c:\\data\\image1.jpg"))
    I got no compiling errors, nor any run-time errors. However, the file that is stored does not seem to be right. I cannot view the image using any image-viewing software.

    Thanks
    Kedar

  12. #12
    Nokia Developer Moderator
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    28,567

    Re: Inverting a bitmap and storing image

    CFbsBitmap::Save creates a single-file .mbm. Most PC software will not be able to do anything with it. You can try MBMViewer (part of the SDK-s, it is in the S60Tools folder), or use the counterpart of CImageDecoder: it is called CImageEncoder.

  13. #13
    Regular Contributor
    Join Date
    Sep 2009
    Posts
    285

    Re: Inverting a bitmap and storing image

    Quote Originally Posted by wizard_hu_ View Post
    ...or use the counterpart of CImageDecoder: it is called CImageEncoder.
    I am trying to use the CImageEncoder class.

    My code uses the Convert function. The function is defined as -
    IMPORT_C void Convert(TRequestStatus *aRequestStatus, const CFbsBitmap &aSource, const CFrameImageData *aFrameImageData=0);
    In my code, my CFBsBitmap is called iB. Hence, I did the following -
    Code:
    	TJpegImageData* imageData=new(ELeave)TJpegImageData;
    	imageData->iSampleScheme=TJpegImageData::EColor444;
    	imageData->iQualityFactor=100; // KJpegQualityFactor;
    	CFrameImageData* iFrameImgData=CFrameImageData::NewL();
    	iFrameImgData->AppendImageData(imageData);
    	
    	CImageEncoder* iImageEncoder = CImageEncoder::FileNewL(CCoeEnv::Static()->FsSession(), _L("c:\\data\\vt.jpg"), _L8("image/jpeg"), CImageEncoder::EOptionAlwaysThread);
    	iImageEncoder->Convert(&as,iB,iFrameImgData);
    However, when I try and run the above, I get the following errors -
    'CImageEncoder::Convert(TRequestStatus *, const CFbsBitmap &, const CFrameImageData *)' (non-static)
    function call '[CImageEncoder].Convert({lval} TRequestStatus, {lval} CFbsBitmap *, {lval} CFrameImageData *)' does not match
    The error seems to be happening at the Convert command only. If I comment out the convert, I get a (0 bytes) file called vt.jpg (at the required location).
    I had a look at the documentation, and the syntax seems pretty correct to me. I also tried looking up the commands in some other threads - again, it seemed correct.

    I also tried the following (which has been used in some examples)-
    Code:
    	iImageEncoder->Convert(as,iB);
    but I still get errors.

    I can't seem to understand what is causing the error.

    Thanks
    Kedar
    Last edited by kedarm; 2010-03-30 at 14:27.

  14. #14
    Nokia Developer Moderator
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    28,567

    Re: Inverting a bitmap and storing image

    The CFbsBitmap has to be an object: iImageEncoder->Convert(&as,*iB,iFrameImgData);

  15. #15
    Regular Contributor
    Join Date
    Sep 2009
    Posts
    285

    Re: Inverting a bitmap and storing image

    I can't believe I missed that! I thought I had it right - looks like I screwed up..

    In my code, I read the filename from the user, and write it to char* fname. I tried the following -
    Code:
    	TPtrC8 ptr8(reinterpret_cast<TUint8 *>(fname));
    	HBufC *buf=HBufC::NewLC(ptr8.Length());
    	buf->Des().Copy(ptr8);
    	CImageEncoder* iImageEncoder = CImageEncoder::FileNewL(CCoeEnv::Static()->FsSession(), *buf, _L8("image/jpeg"), CImageEncoder::EOptionAlwaysThread);
    which is giving the following error -
    SYSTEM ERROR -12
    However, if I replace the *buf with _L("c:\\vt\\img.jpg"), the code works fine.

    Why does *buf not work?

    I used the HBufC method since it had worked for me the last time I used CImageEncoder.

    Thanks
    kedar
    Last edited by kedarm; 2010-03-30 at 22:04.

Page 1 of 2 12 LastLast

Similar Threads

  1. Storing Images .as byte[] vs .png format [HELP NOKIA!]
    By earamsey in forum Mobile Java General
    Replies: 6
    Last Post: 2007-10-10, 15:06
  2. Storing Images .as byte[] vs .png format [HELP NOKIA!]
    By earamsey in forum Mobile Java Games
    Replies: 4
    Last Post: 2007-10-01, 15:22

Posting Permissions

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