You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UWP环境下InkCanvas绘制内容到8bpp图像自动转32bpp问题求解

核心原因

Win2D的CanvasRenderTarget默认使用32位BGRA格式作为渲染缓存,无论输入源的位深是多少,绘制过程都会统一转换为32位处理,直接调用SaveAsync方法仅支持输出24/32位色深的图像,原生不支持直接导出8bpp格式。

解决方案

你可以跳过Win2D的默认保存逻辑,手动将渲染结果转换为8bpp格式后再编码输出,具体实现步骤如下:

  • 从渲染完成的CanvasRenderTarget中读取32位原始像素数据
  • 根据使用场景配置8bpp对应调色板,签名场景推荐使用256级灰度调色板即可满足需求
  • 将32位像素映射为8bpp索引值,使用BitmapEncoder指定8bpp格式完成编码

修改后的实现代码

Image imgToEdit;
InkCanvas inkCanvas;
file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(Ambiente.imgBlankFirma);

await file.CopyAsync(photoFolder, NomeFile, NameCollisionOption.ReplaceExisting);
file = await photoFolder.GetFileAsync(NomeFile);

imgToEdit = imgFirma;
inkCanvas = inkCanvasFirma;

if (inkCanvas.InkPresenter.StrokeContainer.GetStrokes().Count <= 0)
{
    errore = true;
    return;
}

var randomAccessStream = await file.OpenReadAsync();
CanvasDevice device = CanvasDevice.GetSharedDevice();
CanvasRenderTarget renderTarget = new CanvasRenderTarget(device, (int)inkCanvas.ActualWidth, (int)inkCanvas.ActualHeight, 96);

using (var ds = renderTarget.CreateDrawingSession())
{
    var image = await CanvasBitmap.LoadAsync(device, randomAccessStream);
    ds.DrawImage(image);
    ds.DrawInk(inkCanvas.InkPresenter.StrokeContainer.GetStrokes());
}
randomAccessStream.Dispose();

// 新增:将渲染结果转换为8bpp灰度Tiff
int pixelWidth = renderTarget.SizeInPixels.Width;
int pixelHeight = renderTarget.SizeInPixels.Height;
// 读取32位像素数据
byte[] pixelData32bpp = renderTarget.GetPixelBytes();
// 构造8bpp像素数组
byte[] pixelData8bpp = new byte[pixelWidth * pixelHeight];
for (int i = 0; i < pixelData32bpp.Length; i += 4)
{
    // 用BT.601灰度公式计算灰度值:Y = 0.299 R + 0.587 G + 0.114 B
    byte b = pixelData32bpp[i];
    byte g = pixelData32bpp[i + 1];
    byte r = pixelData32bpp[i + 2];
    byte gray = (byte)(r * 0.299 + g * 0.587 + b * 0.114);
    pixelData8bpp[i / 4] = gray;
}

// 生成256级灰度调色板
var palette = new BitmapPalette(new List<Color>());
for (int i = 0; i < 256; i++)
{
    palette.Colors.Add(Color.FromArgb(255, (byte)i, (byte)i, (byte)i));
}

// 编码保存
using (var fileStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
    BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.TiffEncoderId, fileStream);
    encoder.SetPixelData(
        BitmapPixelFormat.Gray8,
        BitmapAlphaMode.Ignore,
        (uint)pixelWidth,
        (uint)pixelHeight,
        96,
        96,
        pixelData8bpp);
    encoder.BitmapPalette = palette;
    await encoder.FlushAsync();
}

内容的提问来源于stack exchange,提问作者SonicMast3r

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 01:15:06