Using Alpha Extraction correctly?

Questions and postings pertaining to the development of ImageMagick, feature enhancements, and ImageMagick internals. ImageMagick source code and algorithms are discussed here. Usage questions which are too arcane for the normal user list should also be posted here.
Post Reply
jamesanderson

Using Alpha Extraction correctly?

Post by jamesanderson »

Hi,

I'm working on a project that involves reading in an image, extracting the alpha channel values and then using those as a roadmap to apply transparency later on. The majority of the code was generated months ago using 6.5.4-Q16 and we recently updated to 6.6.0. I'm wondering if something changed between now and version 6.5.4, as the process I was using that worked does not work anymore.

Basically I perform these steps using the following functions (left out the arguments to make this quick)

ReadImage() // get image from file
CloneImage() // make a copy
SetImageAlphaChannel() // use ExtractAlphaChannel value as argument
TransformImageColorspace() // convert to YUV
ImageToBlob() // convert to blob

This process used to produce (what looked like) a black and white copy of my image where the black regions were the transparent values. Now, after upgrading to 6.6.0 what I get out of it is a series of CF and 91 hex values which essentially creates an entirely pink image.

So, I'm wondering what could have changed that would have caused this? I'm thinking it's either a problem with the cloning or the alpha extraction.

Thanks,
James
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: Using Alpha Extraction correctly?

Post by magick »

Nothing stands out where we would expect a change in behavior. If you post a small complete program that we can download and reproduce the problem, we'll investigate further.
jamesanderson

Re: Using Alpha Extraction correctly?

Post by jamesanderson »

I can't attach a full working application, as what I'm using it for is part of a much larger app. Anyway, here's an excerpt of code that will hopefully show exactly what I'm doing. I'd be happy to answer any questions about it. The purpose of this process is to overlay a logo onto a video. What we're hoping for is the ability to reproduce the transparency accurately. Our process for overlaying blends the logo with the video pixel by pixel. Both are YUV.

To provide a visual example I'd like to attach a couple images that show the differences. How is that done?

Code: Select all

HX_RESULT LogoOverlayManager::PrepareOverlay()
{
    HX_RESULT ret = HXR_OK;
    ExceptionInfo *exception;    
    ImageInfo *image_info2, *image_info3, *alpha_info;
     
    // initialize the image info structure
    MagickCoreGenesis(NULL,MagickTrue);
    exception=AcquireExceptionInfo();

    image_info2 = CloneImageInfo((ImageInfo *) NULL);
    image_info3 = CloneImageInfo((ImageInfo *) NULL);
    alpha_info = CloneImageInfo((ImageInfo *) NULL);


    // get the overlay image from a file or the overlayimage.h version
    if(m_pCompositeImageFilename.IsEmpty())
    {
	// overlayimage.h
	int imageSize =  sizeof(g_pOverlayImageBlob) / sizeof(UCHAR);
        m_pOverlayImage = BlobToImage(image_info2,g_pOverlayImageBlob, imageSize,exception);
    }
    else 
    {     
	// file
        (void) strcpy(image_info2->filename,m_pCompositeImageFilename); 
        m_pOverlayImage = ReadImage(image_info2,exception);
    }
    


    // no overlay image, fail
    if(m_pOverlayImage == NULL)
    {
        ret = HXR_FAIL;
    }
	
	
    // overlay image, succeed 
    if(SUCCEEDED(ret))
    {
	// get image info
        m_iCompositeImageWidth = m_pOverlayImage->magick_columns;
        m_iCompositeImageHeight = m_pOverlayImage->magick_rows;        
        m_pCompositeImageFormat = m_pOverlayImage->magick;

        // resize the image based on set scale percentage
        ret = ScaleOverlay();								

	// resize successful
        if(SUCCEEDED(ret))
        {
            int length = 0;	

			// if alpha channel exists, clone and convert alpha channel
			m_bAlphaChannelPresent = GetImageAlphaChannel(m_pOverlayImage);					
			if(m_bAlphaChannelPresent == MagickTrue && m_bEnableTransparency) 
			{
				// extract the alpha channel
				m_pAlphaImage = CloneImage(m_pOverlayImage, m_iCompositeImageWidth, m_iCompositeImageHeight, MagickFalse, exception);
				m_bAlphaChannelPresent = SetImageAlphaChannel(m_pAlphaImage, ExtractAlphaChannel);

			        // this is to overcome the behavior of Imagemagick. Without
			        // a filename, IM would not decompress the image even if we 
                                // ask it to write it to a blob(and not a file)
				(void) strcpy(alpha_info->filename,"alpha.yuv");
				m_pAlphaImageFormat = m_pAlphaImage->magick;

				// convert alpha image to YUV
				alpha_info->colorspace = YUVColorspace;
				m_pAlphaImageFormat = "YUV";
				strcpy(alpha_info->magick, m_pAlphaImageFormat);
				(void) TransformImageColorspace((Image *) m_pAlphaImage, YUVColorspace);
				m_pAlphaImageBlob = ImageToBlob(alpha_info,(Image *) m_pAlphaImage, (size_t*) &length , exception);

				if(m_pAlphaImageBlob == NULL)
				{
					return HXR_FAIL;
				}
			}
			else // make alpha NULL
			{
				m_pAlphaImage = NULL;
			} 

			// convert overlay image to YUV
            (void) strcpy(image_info3->filename,"foobar.yuv");			 
	    image_info3->colorspace = YUVColorspace; 
            m_pCompositeImageFormat = "YUV";      
            strcpy(image_info3->magick, m_pCompositeImageFormat);
            (void) TransformImageColorspace((Image *) m_pOverlayImage,YUVColorspace);
            m_pCompositeImageBlob = ImageToBlob(image_info3,(Image *) m_pOverlayImage, (size_t*) &length , exception);
            
			// no conversion, fail
            if(m_pCompositeImageBlob == NULL)
            {
                ret = HXR_FAIL;
            }
        }

    }

    HX_ASSERT(SUCCEEDED(ret));

    // clean up
    exception=DestroyExceptionInfo(exception);
    DestroyImageInfo(image_info2);
    DestroyImageInfo(image_info3);
    DestroyImageInfo(alpha_info);

    return ret;

}
Again, if I could attach an image or two you could more clearly see what I'm talking about.

-James
jamesanderson

Re: Using Alpha Extraction correctly?

Post by jamesanderson »

By the way, my problems would be solved if I could find a copy of version 6.5.4-Q16 for windows. Any good recommendations as to where to find that?

-James
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Using Alpha Extraction correctly?

Post by snibgo »

You can put images on the web somewhere, and paste the URLs here.

I have a distribution of 6.5.8-10 for Windows 64-bit static, executables but not source, if that will help. I can put it on the web.

Sorry, I can't help with the code. But if you can provide a minimal program and image files that show the problem, that might help the developers nail down the problem.
snibgo's IM pages: im.snibgo.com
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Using Alpha Extraction correctly?

Post by fmw42 »

jamesanderson

Re: Using Alpha Extraction correctly?

Post by jamesanderson »

Thanks to everyone for their help, however, I've found the solution. It appears as though reading in the file a second time and using that to extract the alpha channel works much better for my purposes. Apparently using CloneImage() create problems in my process. All is solved, thanks again!

-James
Post Reply