簡體   English   中英

向圖像調色板添加顏色

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM