Results 1 to 3 of 3

Thread: Setting the alpha bit on a per pixel basis

  1. #1
    Junior Member
    Join Date
    Sep 2008
    Posts
    3

    Setting the alpha bit on a per pixel basis

    I am using ShivaVG and am developing an application that loads a JPEG via the IJG JPEG Library. The user has the option of setting a "transparency color" from the image as the transparency color. I have a routine that computes a euclidean mean distance from the color based upon Red, Green and Blue distance and determines if the color is within a threshold of similarity [due to compression algorithm]. If it is similar, then set the alpha channel to 100% transparent.

    My question is how do I access the individual pixel information after it has been loaded from the JPEG and into a VGImage? And set the pixel's Alpha channel?

    Here is how I am loading the image [taken from ShivaVG examples]:
    Code :
    VGImage cLoader::createImageFromJpeg(const char *filename)
    {
    	FILE *infile;
      	struct jpeg_decompress_struct jdc;
      	struct jpeg_error_mgr jerr;
      	JSAMPARRAY buffer;  
      	unsigned int bstride;
      	unsigned int bbpp;
     
      	VGImage img;
      	VGubyte *data;
      	unsigned int width;
      	unsigned int height;
      	unsigned int dstride;
      	unsigned int dbpp;
     
      	VGubyte *brow;
      	VGubyte *drow;
      	unsigned int x;
      	unsigned int lilEndianTest = 1;
      	VGImageFormat rgbaFormat;
     
      	/* Check for endianness */
      	if (((unsigned char*)&lilEndianTest)[0] == 1)
        	rgbaFormat = VG_lABGR_8888;
      	else rgbaFormat = VG_lRGBA_8888;
     
      	/* Try to open image file */
      	infile = fopen(filename, "rb");
      	if (infile == NULL) 
      	{
        	printf("Failed opening '%s' for reading!\n", filename);
        	return VG_INVALID_HANDLE; 
        }
     
      	/* Setup default error handling */
      	jdc.err = jpeg_std_error(&jerr);
      	jpeg_create_decompress(&jdc);
     
      	/* Set input file */
      	jpeg_stdio_src(&jdc, infile);
     
      	/* Read header and start */
      	jpeg_read_header(&jdc, TRUE);
      	jpeg_start_decompress(&jdc);
      	width = jdc.output_width;
      	height = jdc.output_height;
     
      	/* Allocate buffer using jpeg allocator */
      	bbpp = jdc.output_components;
      	bstride = width * bbpp;
      	buffer = (*jdc.mem->alloc_sarray)((j_common_ptr) &jdc, JPOOL_IMAGE, bstride, 1);
     
      	/* Allocate image data buffer */
      	dbpp = 4;
      	dstride = width * dbpp;
      	data = (VGubyte*)malloc(dstride * height);
     
      	/* Iterate until all scanlines processed */
      	while (jdc.output_scanline < height) 
      	{
        	/* Read scanline into buffer */
        	jpeg_read_scanlines(&jdc, buffer, 1);    
        	drow = data + (height-jdc.output_scanline) * dstride;
        	brow = buffer[0];
     
        	/* Expand to RGBA */
        	for (x=0; x<width; ++x, drow+=dbpp, brow+=bbpp) 
        	{
          		switch (bbpp) 
          		{
          			case 4:
            				drow[0] = brow[0];
            				drow[1] = brow[1];
            				drow[2] = brow[2];
            				drow[3] = brow[3];
            				break;
          			case 3:
            				drow[0] = brow[0];
            				drow[1] = brow[1];
            				drow[2] = brow[2];
            				drow[3] = 255;
            				break; 
            	}
        	}
      	}
     
      	/* Create VG image */
      	img = vgCreateImage(rgbaFormat, width, height, VG_IMAGE_QUALITY_BETTER);
     
      	if (img != VG_INVALID_HANDLE)
      	{
      		vgImageSubData(img, data, dstride, rgbaFormat, 0, 0, width, height);
      	}  
      	/* Cleanup */
      	jpeg_destroy_decompress(&jdc);
      	fclose(infile);
      	free(data);
     
      	return img;
    };

  2. #2
    Senior Member
    Join Date
    Feb 2006
    Posts
    115

    Re: Setting the alpha bit on a per pixel basis

    Why not just do the calculation after you decompress the jpg, and before you upload it with the vgImageSubData() call?

    I suppose if you NEED to do it afterward, you could use vgGetImageSubData(), modify the data and then call vgImageSubData() again. Seems like a waste though. Alternatively, you could try if there is an Image Filter function what suits your needs (like vgColorMatrix()/vgLookup[Single]()). You may need to massage the function input a bit though to get those to work as you like.

  3. #3
    Junior Member
    Join Date
    Sep 2008
    Posts
    3

    Re: Setting the alpha bit on a per pixel basis

    Quote Originally Posted by Ivo Moravec
    Why not just do the calculation after you decompress the jpg, and before you upload it with the vgImageSubData() call?

    I suppose if you NEED to do it afterward, you could use vgGetImageSubData(), modify the data and then call vgImageSubData() again. Seems like a waste though. Alternatively, you could try if there is an Image Filter function what suits your needs (like vgColorMatrix()/vgLookup[Single]()). You may need to massage the function input a bit though to get those to work as you like.
    Thanks Ivo, I didn't even think to check while I was loading the image. I made it a little easier for me by implementing a pixel color based upon byte aligned struct

    Code :
    #pragma pack(push)  /* push current alignment to stack */
    #pragma pack(1)     /* set alignment to 1 byte boundary */
     
    typedef union
    {
    	VGubyte red;
    	VGubyte green;
    	VGubyte blue;
    	VGubyte alpha;
    } pixelcolor;  //32 bit RGBA color
     
    #pragma pack(pop)   /* restore original alignment from stack */

    Then changed the code to:
    Code :
            VGubyte *brow;
      	pixelcolor *drow;
    .....
    .....
            /* Allocate buffer using jpeg allocator */
      	bbpp = jdc.output_components;
      	bstride = width * bbpp;
      	buffer = (*jdc.mem->alloc_sarray)((j_common_ptr) &jdc, JPOOL_IMAGE, bstride, 1);
     
      	/* Allocate image data buffer */
      	dbpp = 4;
      	dstride = width * dbpp;
      	data = (pixelcolor*)malloc(width * height);
     
      	/* Iterate until all scanlines processed */
      	while (jdc.output_scanline < height) 
      	{
        	/* Read scanline into buffer */
        	jpeg_read_scanlines(&jdc, buffer, 1);    
        	drow = data + (height-jdc.output_scanline) * width;
        	brow = buffer[0];
     
        	/* Expand to RGBA */
        	for (x=0; x<width; ++x, drow++, brow+=bbpp) 
        	{
          		switch (bbpp) 
          		{
          			case 4:
            				drow->red = brow[0];
            				drow->green = brow[1];
            				drow->blue = brow[2];
            				drow->alpha = brow[3];
            				break;
          			case 3:
            				drow->red = brow[0];
            				drow->green = brow[1];
            				drow->blue = brow[2];
            				drow->alpha = 255;
            				break; 
            	}
            	if (in_hastransparency)
            	{
            		if (isInTolerance(*drow, in_transcolor))
            		{
            			drow->alpha = 0;
            		}
            	}
        	}
      }

    I'm still learning the VG and vector graphics implementations....

Similar Threads

  1. Replies: 0
    Last Post: 08-02-2012, 09:18 AM
  2. 32 bit textures on 16 bit framebuffer
    By muratmat in forum OpenGL ES general technical discussions
    Replies: 3
    Last Post: 08-21-2008, 07:59 PM

Posting Permissions

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