Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Image resized error: CGBitmapContextCreate: unsupported parameter

I am using the following code (from a blog post) to resize an image

if (inImage.size.width <= inImage.size.height) {
    // Portrait
    ratio = inImage.size.height / inImage.size.width;
    resizedRect = CGRectMake(0, 0, width, width * ratio);
}
else {
    // Landscape
    ratio = inImage.size.width / inImage.size.height;
    resizedRect = CGRectMake(0, 0, height * ratio, height);
}

CGImageRef          imageRef = [inImage CGImage];
CGImageAlphaInfo    alphaInfo = CGImageGetAlphaInfo(imageRef);

if (alphaInfo == kCGImageAlphaNone)
    alphaInfo = kCGImageAlphaNoneSkipLast;

CGContextRef bitmap = CGBitmapContextCreate(
                                            NULL,
                                            resizedRect.size.width,     // width
                                            resizedRect.size.height,        // height
                                            CGImageGetBitsPerComponent(imageRef),   // really needs to always be 8
                                            4 * resizedRect.size.width, // rowbytes
                                            CGImageGetColorSpace(imageRef),
                                            alphaInfo
                                            );

but for some reason depending on the size I am try to resize to I get the following error generated

CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 32 bits/pixel; 3-component colorspace; kCGImageAlphaNoneSkipFirst; XXX bytes/row.

where XXX differs depending on which image.

The rect I am creating is propotional to the image, I take a ratio from the width/height (depending on aspect) and multiple that be target width/height.

Here are some examples (X errors, / doesnt), the resize size will be 50xX or Xx50 depending on aspect:

Source   50x50   69x69
430x320  /      X
240x320  /      /
272x320  /      /
480x419  /      X
426x320  X      X
480x256  X      X
like image 667
Anthony Main Avatar asked Feb 10 '10 07:02

Anthony Main


1 Answers

Where you wrote thumbRect, did you mean resizedRect? thumbRect does not otherwise occur.

I suspect the problem is that resizedRect.size.width is non integral. Note that it's floating point.

The width and bytesPerRow parameters of CGBitmapContextCreate are declared as integers. When you pass a floating point value, such as here, it gets truncated.

Suppose your resizedRect.size.width is 1.25. Then you will end up passing 1 for the width, and floor(1.25 * 4) == 5 as the bytes per row. That's inconsistent. You always want to pass four times whatever you passed for the width for the bytes per row.

You can also just leave bytesPerRow as 0, by the way. Then the system picks the best bytesPerRow (which is often larger than 4 times the width - it pads out for alignment).

like image 160
Ken Avatar answered Nov 12 '22 09:11

Ken