wmjordan/PDFPatcher · error · MuException
无法渲染页面:{(page.PageNumber + 1).ToText()}
Error message
无法渲染页面:{(page.PageNumber + 1).ToText()} What it means
Thrown as a MuException when MuPDF's Pixmap.Create returns null while allocating the output pixmap for a page render in InternalRenderPage. Pixmap.Create fails when the computed BBox has non-positive dimensions after rounding, when the requested area is too large to allocate, or when the resolved colorspace is invalid. The message reports the 1-based page number (page.PageNumber + 1). Note this fires only at allocation time; later drawing errors surface from page.RunContents/RunAnnotations.
Source
Thrown at App/Processor/Mupdf/MuPDFExtensions.cs:151
return StringBuilderCache.GetStringAndRelease(sb);
}
#region 渲染页面
public static Bitmap RenderBitmapPage(this Page page, int width, int height, ImageRendererOptions options, Cookie cookie) {
using var pix = InternalRenderPage(page, width, height, options, cookie);
return pix?.ToBitmap(options);
}
static Pixmap InternalRenderPage(Page page, int width, int height, ImageRendererOptions options, Cookie cookie) {
var b = page.Bound;
if (b.Width == 0 || b.Height == 0) {
return null;
}
var ctm = CalculateMatrix(page, width, height, options);
var bbox = width > 0 && height > 0 ? new BBox(0, 0, width, height) : b.Transform(ctm).Round();
var pix = Pixmap.Create(((ColorspaceKind)options.ColorSpace).SubstituteDefault(ColorspaceKind.RGB), bbox)
?? throw new MuException($"无法渲染页面:{(page.PageNumber + 1).ToText()}");
pix.Clear(0xFF);
try {
using var dev = Device.NewDraw(pix, Matrix.Identity);
if (options.LowQuality) {
dev.EnableDeviceHints(DeviceHints.DontInterpolateImages | DeviceHints.NoCache);
}
if (cookie.IsCancellationPending) {
goto CANCEL;
}
page.RunContents(dev, ctm, cookie);
if (!options.HideAnnotations) {
page.RunAnnotations(dev, ctm, cookie);
page.RunWidgets(dev, ctm, cookie);
}
dev.Close();
if (cookie.IsCancellationPending) {
goto CANCEL;
View on GitHub (pinned to 4782bbd9ad)
Solutions
- Clamp width/height and DPI before calling RenderBitmapPage so the resulting pixmap (width*height*components bytes) stays within memory limits.
- If you pass height==0 (as Worker.cs does), verify the page Bound is non-degenerate and that ImageWidth * (Bound.Height/Bound.Width) is a positive, finite number.
- Wrap the RenderBitmapPage call in try/catch(MuException) and treat the page as unrenderable (skip / show placeholder) rather than aborting the batch.
- Validate that options.ColorSpace maps to a real ColorspaceKind before rendering; pass a known colorspace (RGB/Gray/BGR).
Example fix
// before
using var bmp = p.RenderBitmapPage(options.ImageWidth, 0, options, cookie);
// after
var bound = p.Bound;
var h = bound.Width > 0 ? (int)Math.Round(options.ImageWidth * bound.Height / bound.Width) : 0;
if (options.ImageWidth <= 0 || h <= 0 || (long)options.ImageWidth * h > 100_000_000) {
Tracker.TraceMessage($"跳过无法渲染的页面:尺寸异常 ({options.ImageWidth}x{h})");
continue;
}
using var bmp = p.RenderBitmapPage(options.ImageWidth, h, options, cookie); Defensive patterns
Strategy: try-catch
Validate before calling
var bound = page.Bound; if (bound.Width <= 0 || bound.Height <= 0) return null; // degenerate page int w = width > 0 ? width : (int)Math.Round(bound.Width * options.ScaleRatio * options.Dpi / 72); int h = height > 0 ? height : (int)Math.Round(bound.Height * options.ScaleRatio * options.Dpi / 72); if (w <= 0 || h <= 0 || (long)w * h > 50_000_000) return null; // too small or too large to allocate
Try / catch
Bitmap bmp = null;
try {
bmp = page.RenderBitmapPage(width, height, options, cookie);
}
catch (MuException ex) when (!cookie.IsCancellationPending) {
Tracker.TraceMessage($"渲染第 {page.PageNumber + 1} 页失败:{ex.Message}");
bmp = null; // skip / placeholder
}
if (bmp == null && cookie.IsCancellationPending) return null; Prevention
- Cap render DPI and explicit width so width*height stays under a memory budget (e.g. 50 MP).
- Never pass a non-positive target height with a positive width unless you have confirmed the page Bound is finite and non-degenerate.
- Resolve options.ColorSpace to a concrete ColorspaceKind (RGB/Gray/BGR) before rendering.
- Always handle the MuException from RenderBitmapPage in batch/worker loops so one bad page does not abort the run.
When it happens
Trigger: RenderBitmapPage(page,width,height,options,cookie) -> InternalRenderPage -> Pixmap.Create(colorspace, bbox) returns null. Two bbox paths: when width>0 && height>0 the bbox is literally (0,0,width,height) so an enormous explicit width/height causes allocation failure; otherwise bbox = b.Transform(ctm).Round() which can round to a degenerate rectangle. Worker.cs calls RenderBitmapPage(options.ImageWidth, 0, ...) so height==0 forces the transform-round path, and a near-zero or negative rounded bbox yields null.
Common situations: Rendering at very high DPI or very large explicit ImageWidth against a big page (pixmap exceeds available memory); a page whose MediaBox/CropBox is tiny or rotated such that the scaled+rounded bbox collapses to zero area; corrupted page geometry where Bound.Width/Height passed the early guard but the transform still degenerates; passing a colorspace option value outside the valid ColorspaceKind enum so SubstituteDefault cannot resolve it.
Related errors
- 不支持的像素格式: colorants={colorants}, spots={spots}, alpha={hasAl
- 在简易书签第 {lineNum} 行的缩进格式不正确。 说明:下级书签最多只能比上级书签多一个缩进标记。
- 简易书签文件内容不足。
- 找不到文件:{sourceFile}
AI-assisted analysis of wmjordan/PDFPatcher@4782bbd9ad (2026-08-13).
Data as JSON: /api/errors/8625ddc4f0305227.
Report an issue: GitHub.