[英]Adding color to an image palette
我在 go 中創建了一個實用程序,它將加載一個圖像(PNG 或 GIF)並用另一個圖像覆蓋它,以幫助調試這個問題我寫了一些代碼,以紅色突出顯示透明度的邊框,所以 red color.Color{R:255,G:0,B:0,A:255}
需要添加到調色板中,如果它已經不在那里,所有這些都使用與圖像疊加過程相同的代碼但理解起來要簡單得多,所以我將在這里分享該代碼。
除了一個方面,我的這個工作正常,那就是我需要將疊加層的調色板添加到源圖像中。
我能夠提取image.Paletted
源圖像的調色板並創建一個新的image.Paletted
,其中包含來自源圖像的所有image.Image.Pix
數據,而image.Paletted.Palette
包含新顏色當使用image.Paletted.SetColorIndex()
使用得到適當的索引之后image.Paletted.Palette.Index()
並將結果保存到一個文件中,沒有任何更改。
奇怪的是,如果我注釋掉所有調色板代碼,覆蓋圖像將寫入文件,但顏色會調整為源圖像中最近的鄰居(根據 go 文檔)。
我不確定為什么修改調色板會阻止我寫入圖像。
這是循環遍歷邊緣像素並為它們繪制紅色的代碼。
func ApplyAttachment(img image.Image, augment *augment.Augment, attachment *augment.Attachment, debug bool) (appliedImage image.Image, err error) {
edgePoints := FindEdge(img, EdgeFromString(attachment.Name))
if debug {
img, err = AddToPallete(img, red)
if err != nil {
logger.Warn("error adding to pallete: %s", err)
}
for _, pt := range edgePoints {
if err = SetImagePixel(&img, pt.X, pt.Y, red); err != nil {
logger.Warn("error setting image pixel: %s", err)
}
}
}
...
這是 AddToPalette 的代碼
// AddToPallete adds a color to the palette of an image.
func AddToPallete(addTo image.Image, c color.Color) (output image.Image, err error) {
srcPallete := extractPallete(addTo)
if !palleteContains(srcPallete, c) {
srcPallete = append(srcPallete, c)
}
pImg := image.NewPaletted(addTo.Bounds(), srcPallete)
ipImg := pImg.SubImage(pImg.Bounds())
output, err = ImageOntoImage(&ipImg, &addTo, augment.Point{X: 0, Y: 0})
return
}
這是 ImageOntoImage 的代碼(將一個image.Image
寫入另一個)
// ImageOntoImage does exactly that
func ImageOntoImage(
source *image.Image,
overlay *image.Image,
startAt augment.Point,
) (output image.Image, err error) {
output = *source
for curY := startAt.Y; curY < startAt.Y+(*overlay).Bounds().Max.Y; curY++ {
for curX := startAt.X; curX < startAt.X+(*overlay).Bounds().Max.X; curX++ {
c := output.At(curX, curY)
oc := (*overlay).At(curX-startAt.X, curY-startAt.Y)
cc := combineColors(c, oc)
if err = SetImagePixel(&output, curX, curY, cc); err != nil {
err = errors.New("Cannot modify image")
return
}
}
}
return
}
// SetImagePixel sets a single pixel of an image to another color
func SetImagePixel(
source *image.Image,
x int,
y int,
color color.Color,
) (err error) {
if poutput, ok := (*source).(*image.Paletted); ok {
cindex := poutput.Palette.Index(color)
poutput.SetColorIndex(x, y, uint8(cindex))
asImg := image.Image(poutput)
source = &asImg
} else if coutput, ok := (*source).(Changeable); ok {
coutput.Set(x, y, color)
} else {
err = errors.New("Cannot modify image")
return
}
return
}
總而言之,當我不展開調色板時,我可以在圖像上設置像素,但是像素會更改為最接近的顏色,當我展開調色板時,像素不會設置,(或者可能是最近的顏色以某種方式接近透明?)
所以我覺得有點尷尬。 我所有的調色板代碼都運行良好。 我被指針灼傷了。 通過創建一個新的調色板圖像,我失去了與指向原始圖像的指針的連接,因此在 go 的范圍內設置像素丟失了。 這就是為什么注釋掉調色板代碼修復它的原因,當設置新像素時仍然使用原始指針,當我創建一個調色板圖像時,我超出了原始指針的范圍,而當它正確設置像素時,保存image 函數仍在引用原始加載的圖像,因此它基本上是創建該圖像的副本。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.