func main() { var ( long = flag.Bool("long", false, "") short = flag.Bool("short", false, "") usage = flag.Bool("usage", false, "") ) os.Args = utils.GetOutput(os.Args) flag.Parse() if *long { fmt.Println( " Applies a simple lomo effect to the image, boosting its saturation and\n" + " composing with a black edged mask.", ) } else if *short { fmt.Println("applies a simple lomo effect to the image") } else if *usage { fmt.Println("lomo [options]") } else { img, data := utils.ReadStdin() // http://the.taoofmac.com/space/blog/2005/08/23/2359 img = contrast.Adjust(img, 1.2) img = channel.Adjust(img, utils.Multiplier(1.2), channel.Saturation) img = blend.Multiply(img, maskFor(img)) utils.WriteStdout(img, data) } }
func runChannel(cmd *hadfield.Command, args []string) { i, data := utils.ReadStdin() var adj utils.Adjuster if utils.FlagVisited("by", cmd.Flag) { adj = utils.Adder(channelBy) } else { adj = utils.Multiplier(channelRatio) } if !(channelRed || channelGreen || channelBlue || channelHue || channelSaturation || channelLightness || channelBrightness || channelAlpha) { channelRed = true channelGreen = true channelBlue = true } if channelRed { i = channel.Adjust(i, adj, channel.Red) } if channelGreen { i = channel.Adjust(i, adj, channel.Green) } if channelBlue { i = channel.Adjust(i, adj, channel.Blue) } if channelHue { i = channel.Adjust(i, adj, channel.Hue) } if channelSaturation { i = channel.Adjust(i, adj, channel.Saturation) } if channelLightness { i = channel.Adjust(i, adj, channel.Lightness) } if channelBrightness { i = channel.Adjust(i, adj, channel.Brightness) } if channelAlpha { i = channel.Adjust(i, adj, channel.Alpha) } utils.WriteStdout(i, data) }
// Vxl pixelates the Image into isometric cubes. It averages the colours and // naïvely darkens and lightens the colours to mimic highlight and shade. func Vxl(img image.Image, height int, flip bool, top, left, right float64) image.Image { b := img.Bounds() pixelHeight := height pixelWidth := int(math.Sqrt(3.0) * float64(pixelHeight) / 2.0) cols := b.Dx() / pixelWidth rows := b.Dy() / pixelHeight // intersection of lines c := float64(pixelHeight) / 2 // gradient of lines k := math.Sqrt(3.0) / 3.0 o := image.NewRGBA(image.Rect(0, 0, pixelWidth*cols, pixelHeight*rows)) // See: http://www.flickr.com/photos/hawx-/8466236036/ inTopSquare := func(x, y float64) bool { if !flip { y *= -1 } return y <= -k*x+c && y >= k*x && y >= -k*x && y <= k*x+c } inBottomRight := func(x, y float64) bool { if !flip { y *= -1 } return x >= 0 && y <= k*x && y >= k*x-c } inBottomLeft := func(x, y float64) bool { if !flip { y *= -1 } return x <= 0 && y <= -k*x && y >= -k*x-c } inHexagon := func(x, y float64) bool { return inTopSquare(x, y) || inBottomRight(x, y) || inBottomLeft(x, y) } topL := channel.AdjustC(utils.Multiplier(top), channel.Lightness) rightL := channel.AdjustC(utils.Multiplier(right), channel.Lightness) leftL := channel.AdjustC(utils.Multiplier(left), channel.Lightness) for col := 0; col < cols; col++ { for row := 0; row < rows; row++ { seen := []color.Color{} for y := 0; y < pixelHeight; y++ { for x := 0; x < pixelWidth; x++ { realY := row*(pixelHeight+int(c)) + y realX := col*pixelWidth + x pixel := img.At(realX, realY) yOrigin := float64(y - pixelHeight/2) xOrigin := float64(x - pixelWidth/2) if inHexagon(xOrigin, yOrigin) { seen = append(seen, pixel) } } } average := utils.Average(seen...) for y := 0; y < pixelHeight; y++ { for x := 0; x < pixelWidth; x++ { realY := row*(pixelHeight+int(c)) + y realX := col*pixelWidth + x yOrigin := float64(y - pixelHeight/2) xOrigin := float64(x - pixelWidth/2) // This stops white bits showing above the top squares. It does mean // the dimensions aren't perfect, but what did you expect with pixels // and trig. It is inefficient though, maybe fix that later? if (!flip && yOrigin < 0) || (flip && yOrigin > 0) { o.Set(realX, realY, topL(average)) } else { if xOrigin > 0 { o.Set(realX, realY, rightL(average)) } else { o.Set(realX, realY, leftL(average)) } } if inTopSquare(xOrigin, yOrigin) { o.Set(realX, realY, topL(average)) } if inBottomRight(xOrigin, yOrigin) { o.Set(realX, realY, rightL(average)) } if inBottomLeft(xOrigin, yOrigin) { o.Set(realX, realY, leftL(average)) } } } } } offsetY := (pixelHeight + int(c)) / 2.0 offsetX := pixelWidth / 2 for col := -1; col < cols; col++ { for row := -1; row < rows; row++ { seen := []color.Color{} for y := 0; y < pixelHeight; y++ { for x := 0; x < pixelWidth; x++ { realY := row*(pixelHeight+int(c)) + y + offsetY realX := col*pixelWidth + x + offsetX if image.Pt(realX, realY).In(b) { pixel := img.At(realX, realY) yOrigin := float64(y - pixelHeight/2) xOrigin := float64(x - pixelWidth/2) if inHexagon(xOrigin, yOrigin) { seen = append(seen, pixel) } } } } if len(seen) <= 0 { continue } average := utils.Average(seen...) for y := 0; y < pixelHeight; y++ { for x := 0; x < pixelWidth; x++ { realY := row*(pixelHeight+int(c)) + y + offsetY realX := col*pixelWidth + x + offsetX yOrigin := float64(y - pixelHeight/2) xOrigin := float64(x - pixelWidth/2) if inTopSquare(xOrigin, yOrigin) { o.Set(realX, realY, topL(average)) } if inBottomRight(xOrigin, yOrigin) { o.Set(realX, realY, rightL(average)) } if inBottomLeft(xOrigin, yOrigin) { o.Set(realX, realY, leftL(average)) } } } } } return o }