Closed davidei1955 closed 2 years ago
Thank you for the report. I'm aware about the issue and I plan to extend the new KnownPixelFormat
enum (so far available as a preview in KGySoft.Drawing.Core, which is the new package of the platform and technology-independent APIs) with a new Format32bppCmyk
field so CMYK format will be natively supported.
As I already implemented CMYK format for WPF (also in preview so far) it will not be a big deal even for the Core package.
However, GDI+ Bitmap
is a bit different. Its CMYK support is actually quite a hack: it uses an unnamed System.Drawing.Imaging.PixelFormat
value (8207) and is not supported on all platforms. Actually you can open the posted image even in my ImagingTools: in Windows Vista or above you will see 8207
as the displayed pixel format. Windows XP behaves differently though: CMYK JPEG images are loaded with Format24bppRgb
pixel format, and CMYK TIFF images with Format32bppArgb
format (if the source image uses 8 bits for each channel).
What you can expect from me:
I was already planning to add CMYK support also to KGySoft.Drawing (starting with 7.0.0 this contains only the GDI+ specific APIs) but maybe only as source format. Meaning, ImageExtensions.ConvertPixelFormat
will support it as source format but (probably) not as a target format.
What you can do today: If you need to use CMYK source images you can try the following workarounds today:
WriteableBitmap
to load the source image, and then access it by WriteableBitmapExtensions.GetReadWriteBitmapData
, where I already implemented CMYK support (requires the KGySoft.Drawing.Wpf package). Then you can use the Clone
extension methods that have a pixelFormat
parameter, which are essentially the same as the ConvertPixelFormat
methods for GDI+ images. The converted IReadWriteBitmapData
can be converted to a GDI+ Bitmap
by the ToBitmap
extension method.Bitmap
you can use the LockBits
method, and then the buffer is exposed by the BitmapData.Scan0
property as you can see here (the solution should be something similar to the WPF version linked above). This way you will have an IReadWriteBitmapData
so the rest is the same as in the previous point with cloning, etc.Bitmap
is loaded with Format48bppRgb
pixel format by the TIFF decoder (at least in Windows Vista and above) so you can use ConvertPixelFormat
as expected.Thanks for the quick response! My current usage requirement is only as a source input to ConvertPixelFormat(), so 'source only' is fine.
My workaround is to convert the cmyk image to rgb thusly:
public static Bitmap AsRgb(this Bitmap img) { if (((int) img.PixelFormat) != 8207) { //8207 == PixelFormat.Cmyk32 return img; } try { return img.To24bppRgb(); } finally { img.Dispose(); } }
The CMYK support of Bitmap
(only as input format) has been released in 7.0.0-preview.2 (see the change log)
ConvertPixelFormat() throws: System.InvalidOperationException: 'Internal Error: Unexpected pixel format 8207' The failing line is: var newImage = original.ConvertPixelFormat(PixelFormat.Format8bppIndexed, PredefinedColorsQuantizer.FromCustomFunction(c => c.ToGray()));
The failing image is attached. Paint, Paint.net, and Photos can all open the image https://user-images.githubusercontent.com/79710713/174828173-be47e13d-a8e5-42ea-97d8-9be913ebde9c.jpg .