Skip to content

Instantly share code, notes, and snippets.

@pwfff
Created July 21, 2018 03:39
Show Gist options
  • Save pwfff/a578be7ef99074b997c274b97b99aa78 to your computer and use it in GitHub Desktop.
Save pwfff/a578be7ef99074b997c274b97b99aa78 to your computer and use it in GitHub Desktop.
package main
import (
"bufio"
"github.com/nfnt/resize"
"image"
"image/color"
"image/draw"
"image/jpeg"
_ "image/png"
"io"
"log"
"os"
"sort"
)
type sortRow struct {
start int
end int
}
type YSorter []color.Color
func (r YSorter) Len() int { return len(r) }
func (r YSorter) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
func (r YSorter) Less(i, j int) bool {
r1, g1, b1, _ := r[i].RGBA()
r2, g2, b2, _ := r[j].RGBA()
y1, _, _ := color.RGBToYCbCr(uint8(r1>>8), uint8(g1>>8), uint8(b1>>8))
y2, _, _ := color.RGBToYCbCr(uint8(r2>>8), uint8(g2>>8), uint8(b2>>8))
return y1 < y2
}
func getPixels(file io.Reader) ([][]color.Color, draw.Image, error) {
img, _, err := image.Decode(file)
if err != nil {
return nil, nil, err
}
bounds := img.Bounds()
width, height := bounds.Max.X, bounds.Max.Y
pixels := getPixels(
b := img.Bounds()
rgba := image.NewRGBA(b)
draw.Draw(rgba, b, img, b.Min, draw.Src)
return pixels, rgba, nil
}
func getPixels(img draw.Image) [][]color.Color {
var pixels [][]color.Color
for y := 0; y < height; y++ {
var row []color.Color
for x := 0; x < width; x++ {
row = append(row, img.At(x, y))
}
pixels = append(pixels, row)
}
return pixels
}
func main() {
baseReader, err := os.Open("city.jpg")
if err != nil {
log.Fatal(err)
}
defer baseReader.Close()
basePixels, baseImage, err := getPixels(baseReader)
if err != nil {
log.Fatal(err)
}
maskReader, err := os.Open("mask.png")
if err != nil {
log.Fatal(err)
}
defer maskReader.Close()
maskPixels, _, err := getPixels(maskReader)
if err != nil {
log.Fatal(err)
}
var maskRows [][]sortRow
for y := range maskPixels {
var rows []sortRow
var start int
var inRow bool
row := maskPixels[y]
for x := range row {
pixel := row[x]
_, _, _, a := pixel.RGBA()
if a == 0 {
if inRow {
rows = append(rows, sortRow{start, x})
inRow = false
}
} else {
if !inRow {
start = x
inRow = true
}
}
}
maskRows = append(maskRows, rows)
}
for y := range maskRows {
for i := range maskRows[y] {
row := maskRows[y][i]
var colors []color.Color
for x := row.start; x < row.end; x++ {
colors = append(colors, baseImage.At(x, y))
}
sort.Sort(YSorter(colors))
j := 0
for x := row.start; x < row.end; x++ {
baseImage.Set(x, y, colors[j])
j++
}
}
}
f, err := os.Create("out.jpg")
if err != nil {
log.Fatal(err)
}
defer f.Close()
w := bufio.NewWriter(f)
jpeg.Encode(w, baseImage, nil)
log.Print(basePixels[1][1].RGBA())
log.Print(maskRows[0])
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment