diff --git a/blend.go b/blend.go index 2c0a13c..647d7d8 100644 --- a/blend.go +++ b/blend.go @@ -85,12 +85,19 @@ func (p *blendWorkerPool) SetImageWorker(newImage *image.RGBA) { func (p *blendWorkerPool) BlendImages(img1 image.Image, img2 image.Image) { log.Println("Blending the images...") - dimensions := getDimensions(img1, img2) + // dimensions := getMaxDimensions(img1, img2) // output image, ready to receive pixel values + dimensions := dimensionsToRectangle(ConfigRegister.OutputWidth, ConfigRegister.OutputHeight) outImg := image.NewRGBA(dimensions) + + // TODO: use a worker pool for those operations ? + // resize image + img1Resized := resize(img1) + img2Resized := resize(img2) + p.RunWorkers(outImg) - p.SendBlendJobs(dimensions, img1, img2) + p.SendBlendJobs(dimensions, img1Resized, img2Resized) // first waitgroup to wait for the results to be ready before closing the channel p.WorkerWG.Wait() @@ -166,7 +173,7 @@ func blendColor(color1 color.Color, color2 color.Color) color.Color { } // creates a new rectangle with the min height and width from both images -func getDimensions(img1 image.Image, img2 image.Image) image.Rectangle { +func getMaxDimensions(img1 image.Image, img2 image.Image) image.Rectangle { // get dimensions for both images size1 := img1.Bounds().Size() size2 := img2.Bounds().Size() @@ -181,3 +188,30 @@ func getDimensions(img1 image.Image, img2 image.Image) image.Rectangle { return image.Rectangle{upLeft, lowRight} } + +// resizes image using dimensions from config register (nearest neighbour interpolation) +func resize(img image.Image) (resized *image.RGBA) { + imgSize := img.Bounds().Size() + dimensions := dimensionsToRectangle(ConfigRegister.OutputWidth, ConfigRegister.OutputHeight) + xscale := float64(imgSize.X) / float64(dimensions.Max.X) + yscale := float64(imgSize.Y) / float64(dimensions.Max.Y) + // creates new rescaled image based on a given image dimensions + resized = image.NewRGBA(dimensions) + // get pixels from the original image + for x := 0; x < dimensions.Max.X; x++ { + for y := 0; y < dimensions.Max.Y; y++ { + xp := int(math.Floor(float64(x) * xscale)) + yp := int(math.Floor(float64(y) * yscale)) + pixel := img.At(xp, yp) + resized.Set(x, y, pixel) + } + } + return +} + +// returns a Rectangle of dimensions x +func dimensionsToRectangle(width int, height int) image.Rectangle { + upLeft := image.Point{0, 0} + lowRight := image.Point{width, height} + return image.Rectangle{upLeft, lowRight} +} diff --git a/config.go b/config.go index 66d0787..8b54a6a 100644 --- a/config.go +++ b/config.go @@ -4,13 +4,18 @@ import ( "encoding/json" "fmt" "os" + "strconv" + "strings" ) type Config struct { - Method string `json:method` - OutputDir string `json:outputdir` - InputDir string `json:inputdir` - BaseImage string `json:baseimage` + Method string `json:method` + OutputDir string `json:outputdir` + InputDir string `json:inputdir` + BaseImage string `json:baseimage` + Dimensions string `json:dimensions` + OutputWidth int `json:output_width` + OutputHeight int `json:output_height` } // loads configuration values from json file @@ -27,5 +32,14 @@ func (c *Config) LoadConfigFromFile(filePath string) { fmt.Println(configuration.OutputDir) } +// Set output file dimensions using string symbol (x) +func (c *Config) SetOutputDimensions() { + split := strings.Split(c.Dimensions, "x") + width, _ := strconv.Atoi(split[0]) + height, _ := strconv.Atoi(split[1]) + c.OutputWidth = width + c.OutputHeight = height +} + // global register to acccess configuration values var ConfigRegister Config diff --git a/main.go b/main.go index 6d90fa4..fca0755 100644 --- a/main.go +++ b/main.go @@ -13,8 +13,12 @@ func main() { flag.StringVar(&ConfigRegister.OutputDir, "output", "./", "Output directory") flag.StringVar(&ConfigRegister.InputDir, "input", "/home/gator/Photos", "Input directory. Where to look the images from") flag.StringVar(&ConfigRegister.BaseImage, "base-img", "", "Path to the base image to work with. Random image if not set") + flag.StringVar(&ConfigRegister.Dimensions, "dimensions", "800x600", "Out image dimensions. x") flag.Parse() + // set output's width and height + ConfigRegister.SetOutputDimensions() + // get two random images and load them var img1 image.Image if ConfigRegister.BaseImage != "" {