Esempio n. 1
0
func blur(img image.Image, howmuch float32) image.Image {
	g := gift.New(gift.Grayscale())
	g.Add(gift.GaussianBlur(howmuch))
	dst := image.NewRGBA(g.Bounds(img.Bounds()))
	g.Draw(dst, img)
	return (dst)
}
Esempio n. 2
0
func varianceF(img image.Image, disk int) (imageF, imageF) {
	m := meanF(img, disk) // gets a grayscale copy of local mean

	// create a grayscale version of the original
	//g := gift.New( gift.Grayscale() )
	//v := image.NewRGBA(g.Bounds(img.Bounds()))
	//g.Draw(v, img)

	g := gift.New(gift.Grayscale())
	dst := image.NewRGBA(g.Bounds(img.Bounds()))
	g.Draw(dst, img)

	bounds := img.Bounds()
	floatData := make([][]float32, bounds.Max.Y-bounds.Min.Y)
	for i := range floatData {
		floatData[i] = make([]float32, bounds.Max.X-bounds.Min.X)
	}
	for y := bounds.Min.X; y < bounds.Max.X; y++ {
		for x := bounds.Min.Y; x < bounds.Max.Y; x++ {
			p1r, p1g, p1b, _ := dst.At(x, y).RGBA()
			g1 := 0.2125*float64(p1r) + 0.7154*float64(p1g) + 0.0721*float64(p1b)
			g2 := float64(m[x][y])

			floatData[x][y] = float32((g1 - g2) * (g1 - g2))
		}
	}
	return m, floatData
}
Esempio n. 3
0
func mean(img image.Image, disk int) image.Image {
	g := gift.New(gift.Grayscale())
	g.Add(gift.Mean(disk, false)) // use square neighborhood
	dst := image.NewRGBA(g.Bounds(img.Bounds()))
	g.Draw(dst, img)
	return (dst)
}
Esempio n. 4
0
func main() {

	if len(os.Args) != 2 {
		fmt.Println("Usage:\tgoimger <file>")
		os.Exit(1)
	}

	srcFileName := os.Args[1]
	srcFile, _ := os.Open(srcFileName)
	src, _, _ := image.Decode(srcFile)

	// let's make a new gift
	g := gift.New(
		gift.Grayscale(),
		gift.UnsharpMask(1.0, 0.5, 0.0),
	)

	// dest - output image
	dest := image.NewRGBA(g.Bounds(src.Bounds()))
	// draw result
	g.Draw(dest, src)

	outFileName := srcFileName + "_goimger.jpg"
	toimg, _ := os.Create(outFileName)
	defer toimg.Close()

	jpeg.Encode(toimg, dest, &jpeg.Options{jpeg.DefaultQuality})
}
Esempio n. 5
0
func main() {
	if len(os.Args) != 2 {
		fmt.Println("Usage:\tspiffy <file>")
		os.Exit(1)
	}

	srcFileName := os.Args[1]
	srcFile, _ := os.Open(srcFileName)
	src, _, _ := image.Decode(srcFile)

	// 1. Create a new GIFT and add some filters:
	g := gift.New(
		gift.Grayscale(),
		gift.UnsharpMask(1.0, 1.0, 0.0),
	)

	// 2. Create a new image of the corresponding size.
	// dst is a new target image, src is the original image
	dst := image.NewRGBA(g.Bounds(src.Bounds()))

	// 3. Use Draw func to apply the filters to src and store the result in dst:
	g.Draw(dst, src)

	outFileName := srcFileName + ".spiffy.jpg"
	toimg, _ := os.Create(outFileName)
	defer toimg.Close()

	jpeg.Encode(toimg, dst, &jpeg.Options{jpeg.DefaultQuality})
}
Esempio n. 6
0
// take an image and revert its rgb channels (255-channel)
func invert(img image.Image) image.Image {

	g := gift.New(gift.Grayscale(),
		gift.Invert())
	dst := image.NewRGBA(g.Bounds(img.Bounds()))
	g.Draw(dst, img)

	return dst
}
Esempio n. 7
0
// try to focus on a specific scale by using a mexican hat filter
func focus(img image.Image, s float32) image.Image {

	onethird := s / 3.0
	small := blur(img, s-onethird)
	large := blur(img, s+onethird)

	bounds := img.Bounds()
	floatData := make([][]float32, bounds.Max.X-bounds.Min.X)
	for i := range floatData {
		floatData[i] = make([]float32, bounds.Max.Y-bounds.Min.Y)
	}

	for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
		for x := bounds.Min.X; x < bounds.Max.X; x++ {
			p1r, p1g, p1b, _ := small.At(x, y).RGBA()
			p2r, p2g, p2b, _ := large.At(x, y).RGBA()
			g1 := 0.2125*float64(p1r) + 0.7154*float64(p1g) + 0.0721*float64(p1b)
			g2 := 0.2125*float64(p2r) + 0.7154*float64(p2g) + 0.0721*float64(p2b)
			floatData[x][y] = float32(g1 - g2)
		}
	}

	min := floatData[0][0]
	max := floatData[0][0]
	for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
		for x := bounds.Min.X; x < bounds.Max.X; x++ {
			if min > floatData[x][y] {
				min = floatData[x][y]
			}
			if max < floatData[x][y] {
				max = floatData[x][y]
			}
		}
	}

	g := gift.New(gift.Grayscale())
	dst := image.NewRGBA(g.Bounds(img.Bounds()))
	g.Draw(dst, img)

	for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
		for x := bounds.Min.X; x < bounds.Max.X; x++ {
			dst.Set(x, y, color.Gray16{uint16((floatData[x][y] - min) / (max - min) * 65535)})
		}
	}
	return dst
}
Esempio n. 8
0
func meanF(img image.Image, disk int) imageF {

	g := gift.New(gift.Grayscale())
	g.Add(gift.Mean(disk, false)) // use square neighborhood
	dst := image.NewRGBA(g.Bounds(img.Bounds()))
	g.Draw(dst, img)

	// now convert this to float array of arrays
	floatData := make([][]float32, dst.Bounds().Max.Y-dst.Bounds().Min.Y)
	for i := range floatData {
		floatData[i] = make([]float32, dst.Bounds().Max.X-dst.Bounds().Min.X)
	}
	bounds := dst.Bounds()
	for y := bounds.Min.X; y < bounds.Max.X; y++ {
		for x := bounds.Min.Y; x < bounds.Max.Y; x++ {
			pr, _, _, _ := dst.At(x, y).RGBA()
			floatData[x][y] = float32(pr) // 0.2125*float32(pr) + 0.7154*float32(pg) + 0.0721*float32(pb)
		}
	}

	return floatData
}
Esempio n. 9
0
func variance(img image.Image, disk int) (image.Image, image.Image) {
	m := mean(img, disk) // gets a grayscale copy

	// create a grayscale version of the original
	g := gift.New(gift.Grayscale())
	v := image.NewRGBA(g.Bounds(img.Bounds()))
	g.Draw(v, img)

	bounds := img.Bounds()
	dst := image.NewGray(bounds)
	for y := bounds.Min.X; y < bounds.Max.X; y++ {
		for x := bounds.Min.Y; x < bounds.Max.Y; x++ {
			p1r, p1g, p1b, _ := v.At(x, y).RGBA()
			p2r, p2g, p2b, _ := m.At(x, y).RGBA()
			g1 := 0.2125*float64(p1r) + 0.7154*float64(p1g) + 0.0721*float64(p1b)
			g2 := 0.2125*float64(p2r) + 0.7154*float64(p2g) + 0.0721*float64(p2b)

			dst.Set(x, y, color.Gray16{uint16(math.Sqrt((g1 - g2) * (g1 - g2)))})
			//fmt.Println("value: ", math.Sqrt((g1-g2) * (g1-g2)))
		}
	}
	return m, dst
}
Esempio n. 10
0
// GreyscaleDctMatrix Computes the Dct of a greyscale image using matrixes
func GreyscaleDctMatrix(im image.Image) uint64 {
	greyFilter := gift.Grayscale()

	convFilter := gift.Convolution([]float32{
		1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1,
	}, true, false, false, 0)
	resizeFilter := gift.Resize(32, 32, gift.LinearResampling)
	g := gift.New(greyFilter, convFilter, resizeFilter)
	dst := image.NewRGBA(g.Bounds(im.Bounds()))
	g.Draw(dst, im)
	/*
		out, _ := os.Create("/Users/danielriley/desktop/output.jpg")
		var opt jpeg.Options
		opt.Quality = 80
		_ = jpeg.Encode(out, dst, &opt) // put quality to 80%

		out1, _ := os.Create("/Users/danielriley/desktop/output1.jpg")
		opt.Quality = 80
		_ = jpeg.Encode(out1, im, &opt) // put quality to 80%
		return 0
	*/
	//width := im.Bounds().Max.X
	//height := im.Bounds().Max.Y
	m := make([][]float64, 32)
	for i := 0; i < 32; i++ {
		m[i] = make([]float64, 32)
		for j := 0; j < 32; j++ {
			_, _, b, _ := dst.At(i, j).RGBA()
			m[i][j] = float64(b)
		}
	}
	/*
		out, _ := os.Create("/Users/danielriley/desktop/output.jpg")
		var opt jpeg.Options
		opt.Quality = 80
		_ = jpeg.Encode(out, dst, &opt) // put quality to 80%

		out1, _ := os.Create("/Users/danielriley/desktop/output1.jpg")
		opt.Quality = 80
		_ = jpeg.Encode(out1, im, &opt) // put quality to 80%
	*/
	imMatrix := FloatMatrix(m)
	dctMatrix := NewDCTMatrix(32)

	// We can safely ignore errors here, since the sizes
	// always match.
	dct, _ := dctMatrix.Multiply(imMatrix)

	dct, _ = dct.Multiply(dctMatrix.Transposed())

	sub, _ := dct.SubMatrix(1, 1, 8, 8)

	values := sub.UnrollX()

	// We need the original values, so we must sort a copy
	cpy := make([]float64, len(values))
	copy(cpy, values)
	sort.Float64s(cpy)
	median := (cpy[64/2-1] + cpy[64/2]) / 2
	fmt.Println("got median ", median)
	bit := uint64(1)
	hash := uint64(0)
	for _, v := range values {
		if v > median {
			hash |= bit
		}
		bit <<= 1
	}

	fmt.Println("calculated hash ", hash)
	return hash

	/*
		imgMtx, err := manipulator.GrayImageToMatrix(img)
		if err != nil {
			panic(err)
		}
		dctMtx, err := createDctMatrix(img.Bounds().Max.X, img.Bounds().Max.Y)
		if err != nil {
			panic(err)
		}

		dctMtxTransp := dctMtx.T() // Transpose

		dctMtx.Mul(dctMtx, imgMtx)
		dctMtx.Mul(dctMtx, dctMtxTransp)

		dctImage, err := manipulator.CropMatrix(dctMtx, 0, 0, 7, 7)
		if err != nil {
			panic(err)
		}
		subsec := dctImage.RawMatrix().Data
		median := median(subsec)
		var one, hash uint64 = 1, 0
		for i := 0; i < len(subsec); i++ {
			current := subsec[i]
			if current > median {
				hash |= one
			}
			one = one << 1
		}
		return hash
	*/
}
Esempio n. 11
0
func (processor *Processor) Execute(src *Image, dst io.Writer, query *Query) {
	processor.gift.Empty()
	quality := 100

	if query.Count() > 0 {
		// resize
		if query.Has("w") || query.Has("h") {
			width := query.GetInt("w")
			height := query.GetInt("h")

			if width > 0 || height > 0 {
				processor.gift.Add(gift.Resize(width, height, gift.LanczosResampling))
			}
		}

		// crop
		if query.Has("c") {
			c := query.GetIntArray("c")
			if len(c) == 4 {
				processor.gift.Add(gift.Crop(image.Rect(c[0], c[1], c[2], c[3])))
			}
		}

		// grayscale
		if query.Has("grayscale") {
			processor.gift.Add(gift.Grayscale())
		}

		// sepia
		if query.Has("sepia") {
			sepia := query.GetInt("sepia")
			if sepia <= 100 {
				processor.gift.Add(gift.Sepia(float32(sepia)))
			}
		}

		// contrast
		if query.Has("contrast") {
			contrast := query.GetInt("contrast")
			processor.gift.Add(gift.Contrast(float32(contrast)))
		}

		// brightness
		if query.Has("brightness") {
			brightness := query.GetInt("brightness")
			processor.gift.Add(gift.Brightness(float32(brightness)))
		}

		// saturation
		if query.Has("saturation") {
			saturation := query.GetInt("saturation")
			processor.gift.Add(gift.Saturation(float32(saturation)))
		}

		// colorize
		if query.Has("colorize") {
			colorize := query.GetIntArray("colorize")
			if len(colorize) == 3 {
				processor.gift.Add(gift.Colorize(float32(colorize[0]), float32(colorize[1]), float32(colorize[2])))
			}
		}

		// colorbalance
		if query.Has("colorbalance") {
			colorbalance := query.GetIntArray("colorbalance")
			if len(colorbalance) == 3 {
				processor.gift.Add(gift.ColorBalance(float32(colorbalance[0]), float32(colorbalance[1]), float32(colorbalance[2])))
			}
		}

		// quality
		if query.Has("q") {
			q := query.GetInt("q")
			if q > 0 && q < 100 {
				quality = q
			}
		}

		// Draw
		if len(processor.gift.Filters) > 0 {
			rgba := image.NewRGBA(processor.gift.Bounds(src.Object.Bounds()))
			processor.gift.Draw(rgba, src.Object)

			jpeg.Encode(dst, rgba, &jpeg.Options{Quality: quality})

			return
		}
	}

	// default
	jpeg.Encode(dst, src.Object, &jpeg.Options{Quality: quality})
}
Esempio n. 12
0
func (r *FilesResource) getImageReader(registry kit.Registry, tmpDir string, file kit.File, width, height int64, filters []string, ip string) (reader kit.ReadSeekerCloser, size int64, err apperror.Error) {
	if width == 0 && height == 0 && len(filters) == 0 {
		reader, err = file.Reader()
		return
	}

	// Dimensions specified.
	// Check if the thumbnail was already created.
	// If so, serve it. Otherwise, create it first.

	if (width == 0 || height == 0) && (file.GetWidth() == 0 || file.GetHeight() == 0) {
		err = &apperror.Err{
			Code:    "image_dimensions_not_determined",
			Message: fmt.Sprintf("The file with id %v does not have width/height", file.GetId()),
		}
		return
	}

	if width < 0 || height < 0 {
		err = apperror.New("invalid_dimensions")
		return
	}

	// If either height or width is 0, determine proper values to presserve aspect ratio.
	if width == 0 {
		ratio := float64(file.GetWidth()) / float64(file.GetHeight())
		width = int64(float64(height) * ratio)
	} else if height == 0 {
		ratio := float64(file.GetHeight()) / float64(file.GetWidth())
		height = int64(float64(width) * ratio)
	}

	maxWidth := registry.Config().UInt("files.thumbGenerator.maxWidth", 2000)
	maxHeight := registry.Config().UInt("files.thumbGenerator.maxHeight", 2000)

	if width > int64(maxWidth) || height > int64(maxHeight) {
		err = &apperror.Err{
			Code:    "dimensions_exceed_maximum_limits",
			Message: "The specified dimensions exceed the maximum limits",
		}
		return
	}

	thumbId := fmt.Sprintf("%v_%v_%v_%v_%v_%v.%v",
		file.GetId(),
		file.GetBucket(),
		file.GetName(),
		strconv.FormatInt(width, 10),
		strconv.FormatInt(height, 10),
		strings.Replace(strings.Join(filters, "_"), ":", "_", -1),
		"jpeg")

	if ok, _ := file.GetBackend().HasFileById("thumbs", thumbId); !ok {
		var channel chan bool
		channel, err = r.thumbnailRateLimiter.Start(ip)
		if err != nil {
			return
		}
		if channel != nil {
			<-channel
		}

		// Thumb does not exist yet, so create it.
		reader, err = file.Reader()
		if err != nil {
			return
		}
		defer reader.Close()

		img, _, err2 := image.Decode(reader)
		if err2 != nil {
			err = apperror.Wrap(err2, "image_decode_error")
			return
		}

		var giftFilters []gift.Filter

		if !(height == 0 && width == 0) {
			giftFilters = append(giftFilters, gift.ResizeToFill(int(width), int(height), gift.LanczosResampling, gift.CenterAnchor))
		}

		for _, filter := range filters {
			if filter == "" {
				continue
			}

			parts := strings.Split(filter, ":")

			if len(parts) > 1 {
				filter = parts[0]
			}

			switch filter {
			case "sepia":
				n := float32(100)

				if len(parts) == 2 {
					x, err2 := strconv.ParseFloat(parts[1], 64)
					if err2 == nil {
						n = float32(x)
					} else {
						err = apperror.New("invalid_sepia_filter_value", true)
						return
					}
				}

				giftFilters = append(giftFilters, gift.Sepia(n))

			case "grayscale":
				giftFilters = append(giftFilters, gift.Grayscale())

			case "brightness":
				n := float32(0)

				if len(parts) == 2 {
					x, err2 := strconv.ParseFloat(parts[1], 64)
					if err2 == nil {
						n = float32(x)
					} else {
						err = apperror.New("invalid_brightness_filter_value", true)
						return
					}
				}

				giftFilters = append(giftFilters, gift.Brightness(n))

			default:
				err = apperror.New("unknown_filter", fmt.Sprintf("Unknown filter: %v", filter), true)
				return
			}
		}

		gift := gift.New(giftFilters...)

		thumb := image.NewRGBA(gift.Bounds(img.Bounds()))
		gift.Draw(thumb, img)

		var writer io.WriteCloser
		_, writer, err = file.GetBackend().WriterById("thumbs", thumbId, true)
		if err != nil {
			return
		}
		defer writer.Close()

		jpeg.Encode(writer, thumb, &jpeg.Options{Quality: 90})

		r.thumbnailRateLimiter.Finish()
	}

	backend := file.GetBackend()
	size, err = backend.FileSizeById("thumbs", thumbId)
	if err != nil {
		return
	}

	reader, err = file.GetBackend().ReaderById("thumbs", thumbId)
	return
}