我正在try 通过使用image.Decode()方法对图像文件(PNG、JPG、GIF和BMP格式)进行解码来创建PDF,以获得image.Image.然后,我将像素数据写入PDF流,该流稍后被压缩.我遇到的问题是,当我解码JPEG时,生成的PDF中的 colored颜色 不正确.所有其他图像格式都能正常工作.我附上了这个问题的截图.

屏幕截图: https://i.imgur.com/Bzz6EnD.png

有人知道是什么导致了这个问题吗?在使用image.Decode()时,是否有特定的方式需要以不同的方式处理JPG?任何关于如何解决这个问题的建议都将不胜感激!

编辑:

代码:

var iData image.Image
iFile, err := os.Open(path)
if err != nil {
  [...]
} else {
  iData, _, err = image.Decode(iFile)
}
[...]
x.Dictionary.Set("ColorSpace", "/DeviceRGB")
x.Dictionary.Set("BitsPerComponent", 8)
for j := 0; j < iData.Bounds().Dy()/pixelMul; j++ {
    for k := 0; k < iData.Bounds().Dx()/pixelMul; k++ {
        r, g, b, _ := iData.At(k*pixelMul, j*pixelMul).RGBA()
        x.Write([]byte{byte(r), byte(g), byte(b)})
    }
}
[...]

在pdf中生成的图像在直接使用jpeg.Decode时看起来是一样的.

我期望在生成的PDF中的图像看起来就像原始的PNG,可能有一点褪色.

原始PNG:https://i.imgur.com/cjjOdxj.png

转换后的JPG:https://i.imgur.com/I5kxTab.jpeg

其他JPG也有相同的问题,例如来自W3Chttps://www.w3.org/MarkUp/Test/xhtml-print/20050519/tests/A_2_1-BF-01.htm的第一个测试JPEG

推荐答案

Color.RGBA()返回0..0xffff范围内的Alpha预乘 colored颜色 分量.

将这样的值转换为byte,如byte(r),将保留其最低8位,与原始值相比,这看起来只是随机的.您需要8位 colored颜色 分量,不要将其转换为byte,而是使用较高的8位,这意味着右移8(或除以256):

x.Write([]byte{byte(r>>8), byte(g>>8), byte(b>>8)})

解释为什么它仍然适用于PNG和GIF,但不适用于JPEG:

解码PNG和GIF图像可能使用使用color.RGBA colored颜色 模型的图像模型,该模型使用8位值存储组件.但它的RGBA.RGBA()方法通过复制原始的8位值将这些值转换为16位值:

func (c RGBA) RGBA() (r, g, b, a uint32) {
    r = uint32(c.R)
    r |= r << 8
    g = uint32(c.G)
    g |= g << 8
    b = uint32(c.B)
    b |= b << 8
    a = uint32(c.A)
    a |= a << 8
    return
}

这意味着如果你取较低的8位,你得到的原始值与你取较高的8位一样.对JPEG图像进行解码可能会使用color.YCbCr色类型,该类型不会重现这种"实现行为".

不要依赖这一点.当您需要16位组件中的8位组件时,请始终使用较高的8位.

Go相关问答推荐

"k8s.io/apimachinery/pkg/runtime.对象(缺少方法DeepCopyBody)

向API网关终结点发出POST请求时出现AWS Lambda With Go:";Rune me.InvalidEntrypoint";错误

切换选项卡时,Goland IDE中的光标自动转移

未对GoFr中的所有请求进行跟踪

mockgen不创建模拟

创建服务时云运行触发器执行失败

戈姆:如何将一对一联系起来?

通过代理从golang连接到ftp

在 go 中,将接收器 struct 从值更改为指针是否向后兼容?

Docker 执行失败并显示cmd/ENTRYPOINT 中的命令未找到

从 ApiGateway 中的 lambda Go 返回 Json

Global Thread-local Storage 在 Go 中的可行性和最佳实践

命令行参数在 Golang 程序中不正确地接受为参数

杜松子wine 和中间件

Gremlin-Go:树步骤不可序列化

Go 信号处理程序不处理终端窗口关闭

如何将具有嵌入式 struct 的 struct 展平为 json

如何使用 Status 字段创建 Kubernetes 对象?

Go:如何通过 GIN-Router 从 AWS S3 将文件作为二进制流发送到浏览器?

如何发送带有登录数据的 GET 请求并将 cookie 数据保存到 txt 文件?