Farben falsch, wenn image.Decode verwendet wird, um JPEG zu dekodieren und in PDF zu schreiben?

PHPz
Freigeben: 2024-02-08 22:40:12
nach vorne
1085 Leute haben es durchsucht

使用 image.Decode 解码 JPEG 并写入 PDF 时颜色不正确?

Der PHP-Editor Zimo hat bei der Verwendung von image.Decode zum Dekodieren von JPEG und zum Schreiben in PDF ein Problem festgestellt, d. h. die Farbe war falsch. Dieses Problem kann durch eine Nichtübereinstimmung des Farbraums verursacht werden. Beim Dekodieren eines JPEG-Bildes müssen Sie sicherstellen, dass der Farbraum des Bildes mit dem Farbraum der PDF-Datei übereinstimmt, da es sonst zu falschen Farben kommt. Um dieses Problem zu lösen, können Sie versuchen, die Funktion image.DecodeConfig zu verwenden, um den Farbmodus des JPEG-Bilds abzurufen und ihn dann mit dem Farbraum der PDF-Datei abzugleichen, um Konsistenz sicherzustellen. Darüber hinaus können Sie auch versuchen, andere Bildverarbeitungsbibliotheken zu verwenden oder den Farbraum des Bildes anzupassen, um dieses Problem zu lösen.

Frageninhalt

Ich habe versucht, image.decode() 方法解码图像文件(png、jpg、gif 和 bmp 格式)来创建 pdf,以获取 image.image zu verwenden. Die Pixeldaten schreibe ich dann in einen PDF-Stream und komprimiere ihn anschließend. Das Problem, das ich habe, ist, dass beim Dekodieren des JPEG die Farben im resultierenden PDF falsch sind. Alle anderen Bildformate funktionieren wie erwartet. Ich habe einen Screenshot des Problems angehängt.

Screenshot: https://i.stack.imgur.com/e3hc8.png

Weiß jemand, was dieses Problem verursacht? Muss ich bei der Verwendung von image.decode() auf bestimmte Weise anders mit JPEGs umgehen? Für Vorschläge zur Lösung dieses Problems wären wir sehr dankbar!

Herausgeber:

Code:

var idata image.image
ifile, err := os.open(path)
if err != nil {
  [...]
} else {
  idata, _, err = image.decode(ifile)
}
Nach dem Login kopieren
[...]
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)})
    }
}
[...]
Nach dem Login kopieren

Bei direkter Verwendung von jpeg.decode sieht das resultierende Bild im PDF gleich aus.

Ich möchte, dass die Bilder im generierten PDF genau wie die Original-PNGs aussehen, vielleicht aber mit einer gewissen Verschlechterung.

Original-PNG: https://i.stack.imgur.com/rnkgq.png

Konvertiertes JPG: https://i.stack.imgur.com/yj69y.jpg

Andere JPEGs haben das gleiche Problem, wie zum Beispiel das erste Test-JPEG von w3c https://www.w3.org/markup/test/xhtml-print/20050519/tests/a_2_1-bf-01.htm

Lösung

color.rgba() 返回 alpha 预乘颜色分量0..0xffff Reichweite.

Wie byte(r) 这样的值转换为 byte 将保留其最低 8 位,与原始值相比,这似乎只是随机的。您需要一个 8 位颜色分量,不要将其转换为 byte, verwendet aber stattdessen die oberen 8 Bits, was eine Rechtsverschiebung um 8 (oder eine Division durch 256) bedeutet:

x.write([]byte{byte(r>>8), byte(g>>8), byte(b>>8)})
Nach dem Login kopieren

Erklärung, warum es immer noch für PNG und GIF funktioniert, aber nicht für JPEG:

Bei der Decodierung von PNG- und GIF-Bildern kann die color.rgba 颜色模型,使用 8 位值存储组件。但其 rgba.rgba()-Methode verwendet werden, um diese Werte durch Kopieren der ursprünglichen 8-Bit-Werte in 16-Bit-Werte umzuwandeln:

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
}
Nach dem Login kopieren

Das heißt, wenn Sie die unteren 8 Bits nehmen, erhalten Sie den gleichen ursprünglichen Wert wie wenn Sie die oberen 8 Bits nehmen. Beim Dekodieren von JPEG-Bildern wird möglicherweise der Farbtyp color.ycbcr verwendet, der dieses „Implementierungsverhalten“ nicht reproduziert.

Verlassen Sie sich nicht darauf. Wenn Sie aus einer 16-Bit-Komponente eine 8-Bit-Komponente benötigen, verwenden Sie immer die höhere 8-Bit-Komponente.

Das obige ist der detaillierte Inhalt vonFarben falsch, wenn image.Decode verwendet wird, um JPEG zu dekodieren und in PDF zu schreiben?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage