Maison >développement back-end >Golang >Convertissez efficacement l'image RBGA en tableau d'octets RVB
J'ai une bibliothèque et une fonction c qui nécessitent un pointeur vers un tableau d'octets contenant un bitmap de 24 bits au format RVB. Le canal alpha n'est pas important et peut être tronqué. J'ai essayé quelque chose comme ceci :
func load(filePath string) *image.RGBA { imgFile, err := os.Open(filePath) if err != nil { fmt.Printf("Cannot read file %v\n", err) } defer imgFile.Close() img, _, err := image.Decode(imgFile) if err != nil { fmt.Printf("Cannot decode file %v\n", err) } return img.(*image.RGBA) } img := load("myimg.png") bounds := img.Bounds() width, height := bounds.Max.X, bounds.Max.Y // Convert to RGB? Probably not... newImg := image.NewNRGBA(image.Rect(0, 0, width, height)) draw.Draw(newImg, newImg.Bounds(), img, bounds.Min, draw.Src) // Pass image pointer to C function. C.PaintOnImage(unsafe.Pointer(&newImg.Pix[0]), C.int(newImg.Bounds().Dy()), C.int(newImg.Bounds().Dx())
Cependant, nrgba semble également être construit sur 4 octets par pixel. Je pourrais résoudre ce problème en utilisant gocv, mais cela semble excessif pour une tâche aussi simple. Existe-t-il un moyen de procéder de manière simple et efficace ?
Il n'y a pas de type d'image RVB dans la bibliothèque standard, mais vous pouvez assembler un tableau RVB très facilement :
bounds := img.bounds() rgb := make([]byte, bounds.dx()*bounds.dy()*3) idx := 0 for y := bounds.min.y; y < bounds.max.y; y++ { for x := bounds.min.x; x < bounds.max.x; x++ { offs := img.pixoffset(x, y) copy(rgb[idx:], img.pix[offs:offs+3]) idx += 3 } }
img.pix
Les données contiennent des valeurs rgba sur 4 octets. Le code ci-dessus copie simplement la valeur RVB des 3 premiers octets de tous les pixels.
Plus rapide grâce à pix
数组中的行是连续的,因此可以通过每行仅调用 pixoffset
一次来改进上述代码,并且每个像素前进 4 个字节。另外,手动复制 3 个字节可能比调用 copy()
(référence si c'est important pour vous) :
bounds := img.Bounds() rgb := make([]byte, bounds.Dx()*bounds.Dy()*3) idx := 0 for y := bounds.Min.Y; y < bounds.Max.Y; y++ { offs := img.PixOffset(bounds.Min.X, y) for x := bounds.Min.X; x < bounds.Max.X; x++ { rgb[idx+0] = img.Pix[offs+0] rgb[idx+1] = img.Pix[offs+1] rgb[idx+2] = img.Pix[offs+2] idx += 3 offs += 4 } }
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!