{"record":{"id":"c1f35bd0640684f5","repo":"wmjordan/PDFPatcher","slug":"colorants-colorants-spots-spots-al","errorCode":null,"errorMessage":"不支持的像素格式: colorants={colorants}, spots={spots}, alpha={hasAlpha}","messagePattern":"不支持的像素格式: colorants=(.+?), spots=(.+?), alpha=(.+?)","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"App/Processor/Mupdf/MuPDFExtensions.cs","lineNumber":286,"sourceCode":"\t\tif (colorants == 3 && hasAlpha && spots == 0) {\r\n\t\t\tvar bmp = new Bitmap(w, h, PixelFormat.Format32bppArgb);\r\n\t\t\tvar data = bmp.LockBits(true);\r\n\t\t\tCopy32bppBgraUnpremultiply(pix, w, h, data);\r\n\t\t\tbmp.UnlockBits(data);\r\n\t\t\treturn bmp;\r\n\t\t}\r\n\r\n\t\tif (colorants == 4 && !hasAlpha && spots == 0) {\r\n\t\t\tvar bmp = new Bitmap(w, h, PixelFormat.Format24bppRgb);\r\n\t\t\tvar data = bmp.LockBits(true);\r\n\t\t\tusing (var rgbPix = pix.ConvertColorspace(ColorspaceKind.RGB, null)) {\r\n\t\t\t\tCopy24bppImage(rgbPix, w, h, false, data);\r\n\t\t\t}\r\n\t\t\tbmp.UnlockBits(data);\r\n\t\t\treturn bmp;\r\n\t\t}\r\n\r\n\t\tthrow new NotSupportedException(\r\n\t\t\t$\"不支持的像素格式: colorants={colorants}, spots={spots}, alpha={hasAlpha}\");\r\n\t}\r\n\r\n\t/// <summary>\r\n\t/// 将 Pixmap 的数据转换为 <see cref=\"Bitmap\"/>。\r\n\t/// </summary>\r\n\tpublic static unsafe Bitmap ToBitmap(this Pixmap pix, ImageRendererOptions options) {\r\n\t\tint width = pix.Width;\r\n\t\tint height = pix.Height;\r\n\t\tbool grayscale = options.ColorSpace == (ColorSpace)ColorspaceKind.Gray;\r\n\t\tbool invert = options.InvertColor;\r\n\t\tvar bmp = new Bitmap(width, height, grayscale ? PixelFormat.Format8bppIndexed : PixelFormat.Format24bppRgb);\r\n\t\tvar imageData = bmp.LockBits(true);\r\n\t\ttry {\r\n\t\t\tif (grayscale) {\r\n\t\t\t\tbmp.CreateStandardGrayscalePalette();\r\n\t\t\t\tCopy8bppImage(pix, width, height, invert, imageData);\r\n\t\t\t}\r","sourceCodeStart":268,"sourceCodeEnd":304,"githubUrl":"https://github.com/wmjordan/PDFPatcher/blob/4782bbd9ada850b56258f29999b7a1c9076c9b1b/App/Processor/Mupdf/MuPDFExtensions.cs#L268-L304","documentation":"Thrown as NotSupportedException by the parameterless ToBitmap(this Pixmap) overload when the pixmap's channel layout does not match one of the four supported conversions: 8bpp grayscale (1 colorant / 1 colorant+alpha), 24bpp RGB (3 colorants, no alpha), 32bpp ARGB (3 colorants + alpha), or CMYK converted to RGB (4 colorants, no alpha). Any spot-color channels (spots>0), CMYK-with-alpha, or an unsupported colorant count falls through to this throw.","triggerScenarios":"Calling ToBitmap() on a Pixmap with spots > 0 (separation/space colorspaces), or colorants==4 && hasAlpha (CMYK+transparency), or colorants not in {1,3,4} (e.g. Lab/DeviceN with an unusual channel count), or colorants==0 && !hasAlpha. This is the parameterless ToBitmap(Pixmap) at line 237, NOT the RenderBitmapPage path which uses ToBitmap(pix, options) that forces RGB/Gray and never reaches this throw.","commonSituations":"Extracting embedded images that use spot/separation colorspaces (Pantone etc.); CMYK images that carry a soft mask or SMask alpha channel; DeviceN or ICCBased colorspaces whose pixmap exposes extra channels; rendering a page whose colorspace was not flattened to RGB before extraction.","solutions":["Flatten the pixmap to DeviceRGB before conversion: using var rgb = pix.ConvertColorspace(ColorspaceKind.RGB, null); then call ToBitmap-equivalent copy on rgb.","Prefer the ToBitmap(this Pixmap pix, ImageRendererOptions options) overload (line 293) or RenderBitmapPage, which allocate a fixed RGB/Gray target and copy with Copy24bppImage/Copy8bppImage, bypassing this guard entirely.","Strip spot channels by converting through an intermediate RGB pixmap so spots/alpha are resolved by MuPDF.","Inspect pix.Colorants, pix.Spots, pix.Alpha before calling and skip/log unsupported layouts instead of letting it throw."],"exampleFix":"// before (throws for spot/CMYK+alpha layouts)\nvar bmp = pix.ToBitmap();\n\n// after (force RGB, no guard hit)\nusing var rgb = pix.ConvertColorspace(ColorspaceKind.RGB, null);\nvar bmp = new Bitmap(rgb.Width, rgb.Height, PixelFormat.Format24bppRgb);\nvar data = bmp.LockBits(true);\nCopy24bppImage(rgb, rgb.Width, rgb.Height, false, data); // or use rgb.ToBitmap(options)","handlingStrategy":"validation","validationCode":"static bool IsSupportedPixmapLayout(Pixmap pix) {\n    int c = pix.Colorants, s = pix.Spots;\n    bool a = pix.Alpha == 1;\n    if (s != 0) return false;\n    if (c == 1) return true;                 // grayscale +/- alpha\n    if (c == 3) return true;                 // RGB or RGBA\n    if (c == 4 && !a) return true;           // CMYK (converted to RGB)\n    return false;\n}","typeGuard":"static bool CanConvertToBitmap(Pixmap pix) =>\n    pix.Spots == 0 && (pix.Colorants == 1 || pix.Colorants == 3 || (pix.Colorants == 4 && pix.Alpha == 0));","tryCatchPattern":"try {\n    return pix.ToBitmap();\n}\ncatch (NotSupportedException) {\n    using var rgb = pix.ConvertColorspace(ColorspaceKind.RGB, null);\n    return rgb.ToBitmap(); // retry on flattened RGB","preventionTips":["Prefer RenderBitmapPage or ToBitmap(pix, ImageRendererOptions) for display paths; they allocate a fixed RGB/Gray target and never hit this guard.","For image extraction, always ConvertColorspace to RGB (or Gray) before copying samples so spot/alpha/CMYK layouts are flattened by MuPDF.","Inspect pix.Colorants/Spots/Alpha and log unsupported layouts instead of letting the throw propagate."],"tags":["mupdf","pixmap","bitmap","colorspace","spot-color","csharp"],"backgroundTag":null,"analyzedSha":"4782bbd9ada850b56258f29999b7a1c9076c9b1b","analyzedAt":"2026-08-13T17:44:50.812Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}