I'm attempting to resize and convert an image into a grayscale slice of float64 (so I can do some transformations on the floats) and then back into an image, but I'm not sure how to convert a []float64 back to RGB or something I can turn into an image.
So far I have:
// colorToGrayScaleFloat64 reduces rgb
// to a grayscale approximation.
func colorToGrayScaleFloat64(c color.Color) float64 {
r, g, b, _ := c.RGBA()
return 0.299*float64(r)
0.587*float64(g)
0.114*float64(b)
}
func getFloatPixels(filePath string) {
size := 32
f, err := os.Open(filePath)
if err != nil {
log.Fatalf("FAILED TO OPEN FILE: %s", err.Error())
}
defer f.Close()
image, _, err := image.Decode(f)
if err != nil {
log.Fatalf("FAILED TO DECODE FILE: %s", err.Error())
}
// Resize image to 32X32
im := imaging.Resize(image, size, size, imaging.Lanczos)
// Convert image to grayscale float array
vals := make([]float64, size*size)
for i := 0; i < size; i {
for j := 0; j < size; j {
vals[size*i j] = colorToGrayScaleFloat64(im.At(i, j))
}
}
fmt.Printf("pixel vals % v\n", vals)
}
Which produces the output:
pixel vals [40315.076 48372.797 48812.780999999995 47005.557 ... 25129.973999999995 24719.287999999997]
How can I convert this pixel []float64 back to an image?
CodePudding user response:
So basically you have the luminosity of the gray pixel, and you want to have a color.Color
value representing it.
This is quite simple: there is a color.Gray
type, and a higher precision color.Gray16
which model the color with its luminosity, so simply create a value of those. They implement color.Color
, so you can use them to set pixels of an image.
col := color.Gray{uint8(lum / 256)}
Also note that your colorToGrayScaleFloat64()
function is already present in the standard lib. There are several converters in the image/color
package as implementations of color.Model
. Use the color.GrayModel
or color.Gray16Model
to convert a color.Color
to a value of type color.Gray
or color.Gray16
which directly store the luminosity of the gray color.
For example:
gray := color.Gray16Model.Convert(img.At(x, y))
lum := float64(gray.(color.Gray16).Y)
Testing it:
c := color.RGBA{111, 111, 111, 255}
fmt.Println("original:", c)
gray := color.Gray16Model.Convert(c)
lum := float64(gray.(color.Gray16).Y)
fmt.Println("lum:", lum)
col := color.Gray{uint8(lum / 256)}
r, g, b, a := col.RGBA()
a >>= 8
fmt.Println("lum to col:", r/a, g/a, b/a, a)
fmt.Println()
This will output (try it on the Go Playground):
original: {111 111 111 255}
lum: 28527
lum to col: 111 111 111 255
Also note that if you want to create an image full of gray pixels, you may use the image.Gray
and image.Gray16
types so when drawing these colors on them, no color conversion will be needed. They also have designated Gray.SetGray()
and Gray16.SetGray16()
methods that directly take colors of these types.
See related: