Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error resizing PNG-8 images #789

Closed
zachwaugh opened this issue Jun 5, 2024 · 3 comments
Closed

Error resizing PNG-8 images #789

zachwaugh opened this issue Jun 5, 2024 · 3 comments
Labels

Comments

@zachwaugh
Copy link
Contributor

I'm working on an app that loads link previews from websites, so I don't have control over the format for the images I get. The one issue currently is with PNG-8 images. They will be fetched and render correctly at original size, but will get an error during resize:

Failed to process the image using processor Resize(size: (512.0, 9999.0) pixels, contentMode: .aspectFit, crop: false, upscale: false)

CGBitmapContextCreate: unsupported parameter combination:
	RGB | 8 bits/component, integer | 1536 bytes/row.
	kCGImageAlphaNone | kCGImageByteOrderDefault | kCGImagePixelFormatPacked

So ultimately can't have an 8-bit/component RGB image with kCGImageAlphaNone. I was able to "fix" it by changing this line to any other value - https://github.com/kean/Nuke/blob/main/Sources/Nuke/Internal/Graphics.swift#L199

Either .premultipliedLast, .premultipliedFirst seem to work fine, but I'm not sure if that is the actual correct fix, and assuming it might break some other format. Here's an example image that reproduces the problem from Daylight's website. This URL will trigger the failure (https://daylightcomputer.com/_next/static/media/OG-homepage.c818d83e.png), also attached the image as well in case that link changes.

LazyImage(request: ImageRequest(url: URL(string: "https://daylightcomputer.com/_next/static/media/OG-homepage.c818d83e.png")!, processors: [.resize(width: 512)])) { ... }

OG-homepage c818d83e

@kean kean added the bug label Jun 5, 2024
@kean
Copy link
Owner

kean commented Jun 5, 2024

Thanks for reporting it and providing the details to reproduce it!

I'm not sure if that is the actual correct fix, and assuming it might break some other format

This line was introduced in order to address the following issues: #782 (comment). I think there is something I'm missing.

@kean
Copy link
Owner

kean commented Jun 8, 2024

Fixed in v12.7.2.

RCA

It was a regression introduced in v12.7 in the scope of the fix for #782.

In 12.7.0, I added the following line to the code that specified the alpha info for CGContext:

        if image.bitsPerPixel == 8 {
            return .none // The only pixel format supported for grayscale CS
        }

I assumed that 8 bpp was only valid for grayscale color spaces, but forgot about the packed pixel formats (kCGImagePixelFormatPacked).

The new version has an additional condition:

        if colorSpace.numberOfComponents == 1 && image.bitsPerPixel == 8 {
            return .none // The only pixel format supported for grayscale CS
        }

I can't say that I'm an expert in pixel formats, so if someone else could review it, that would be fantastic. I'm also open to suggestions for how to improve it.

Debug

Here's some more information from CoreGraphics if you turn the debug flags on:


<CGImage 0x10460eff0> (IP)
	<<CGColorSpace 0x60000260d7a0> (kCGColorSpaceIndexed; base <CGColorSpace 0x60000260d320> (kCGColorSpaceICCBased; kCGColorSpaceModelRGB; sRGB IEC61966-2.1))>
		width = 1200, height = 642, bpc = 8, bpp = 8, row bytes = 1200 
		kCGImageAlphaNone | 0 (default byte order)  | kCGImagePixelFormatPacked 
		is mask? No, has masking color? No, has soft mask? No, has matte? No, should interpolate? Yes


CGBitmapContextCreate: unsupported parameter combination:
 	RGB 
	8 bits/component, integer
 	2272 bytes/row
	kCGImageAlphaNone
	kCGImageByteOrderDefault
	kCGImagePixelFormatPacked
	Valid parameters for RGB color space model are:
	16  bits per pixel,		 5  bits per component,		 kCGImageAlphaNoneSkipFirst
	32  bits per pixel,		 8  bits per component,		 kCGImageAlphaNoneSkipFirst
	32  bits per pixel,		 8  bits per component,		 kCGImageAlphaNoneSkipLast
	32  bits per pixel,		 8  bits per component,		 kCGImageAlphaPremultipliedFirst
	32  bits per pixel,		 8  bits per component,		 kCGImageAlphaPremultipliedLast
	32  bits per pixel,		 10 bits per component,		 kCGImageAlphaNone|kCGImagePixelFormatRGBCIF10|kCGImageByteOrder16Little
	64  bits per pixel,		 16 bits per component,		 kCGImageAlphaPremultipliedLast
	64  bits per pixel,		 16 bits per component,		 kCGImageAlphaNoneSkipLast
	64  bits per pixel,		 16 bits per component,		 kCGImageAlphaPremultipliedLast|kCGBitmapFloatComponents|kCGImageByteOrder16Little
	64  bits per pixel,		 16 bits per component,		 kCGImageAlphaNoneSkipLast|kCGBitmapFloatComponents|kCGImageByteOrder16Little
	128 bits per pixel,		 32 bits per component,		 kCGImageAlphaPremultipliedLast|kCGBitmapFloatComponents
	128 bits per pixel,		 32 bits per component,		 kCGImageAlphaNoneSkipLast|kCGBitmapFloatComponents
See Quartz 2D Programming Guide (available online) for more information.

@kean kean closed this as completed Jun 8, 2024
@zachwaugh
Copy link
Contributor Author

Thanks for the quick fix!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants