示例#1
0
//Creating a thumbnail from a JPEG is straightforwards
func (p *JpegPhoto) Thumbnail(in io.ReadSeeker, longSide int) (io.ReadSeeker, string, error) {

	//first we need to read the image.
	img, _, err := image.Decode(in)
	if err != nil {
		return nil, "", err
	}
	var w, h int
	aspect := float64(p.Width) / float64(p.Height)
	if p.Width > p.Height {
		w, h = longSide, int(float64(longSide)/aspect)
	} else {
		w, h = int(float64(longSide)*aspect), longSide
	}
	//we need to do this switch twice. first to check if we need to swap width/height
	//as we resize before rotation/flip
	//then after to do the resize/flip.
	switch p.Orientation {
	case OrientedNormal90, OrientedMirror90, OrientedNormal270, OrientedMirror270:
		//flip then rotate 270
		w, h = h, w
	}
	//now create thumbnail.
	img = imaging.Thumbnail(img, w, h, imaging.Box)
	//now we need to rotate/flip it to match the ExifOrientation flag
	switch p.Orientation {
	case OrientedNormal:
		//nothing
	case OrientedMirror:
		//flip only
		img = imaging.FlipH(img)
	case OrientedNormal90:
		//rotate 90
		img = imaging.Rotate90(img)
	case OrientedMirror90:
		//flip and rotate 90
		img = imaging.FlipH(imaging.Rotate90(img))
	case OrientedNormal180:
		//rotate 180
		img = imaging.Rotate180(img)
	case OrientedMirror180:
		//flip then rotate 180
		img = imaging.FlipH(imaging.Rotate180(img))
	case OrientedNormal270:
		//rotate 270 (90 anti-clockwise)
		img = imaging.Rotate270(img)
	case OrientedMirror270:
		//flip then rotate 270
		img = imaging.FlipH(imaging.Rotate270(img))
	}
	//now re-encode
	var wr bytes.Buffer
	err = jpeg.Encode(&wr, img, nil)
	return bytes.NewReader(wr.Bytes()), "image/jpeg", err
}
示例#2
0
func (ipo *ImageProcessorOptions) ProcessImage(source *Image) (*Image, error) {
	dest := &Image{format: source.format}

	var wip image.Image

	if ipo.ScaleX == -1 {
		wip = imaging.FlipH(source.image)
	} else {
		wip = source.image
	}

	if ipo.X != 0 || ipo.Y != 0 || ipo.Width != source.Width() || ipo.Height != source.Height() {
		r := image.Rectangle{image.Point{int(ipo.X), int(ipo.Y)}, image.Point{int(ipo.X + ipo.Width), int(ipo.Y + ipo.Height)}}
		wip = imaging.Crop(wip, r)
	}

	var err error
	switch dest.format {
	case JPEG:
		err = jpeg.Encode(&dest.buffer, wip, &jpeg.Options{int(ipo.Quality)})
	case PNG:
		err = png.Encode(&dest.buffer, wip)
	default:
		return nil, errors.New("attempt to encode to unsupported image format")
	}

	return dest, err
}
示例#3
0
// AddImage examines the provided image and compares it to the images already
// stored in the map of prototype images.  If this image is unique and doesn't
// match any of the prototype images, including rotations or mirror copies, then
// it is added to the map of prototype images.
func (p *ImageSet) AddImage(img image.Image, x, y int) {
	index := y*p.stride + x
	images := make([]image.Image, 8)
	images[0] = img
	images[1] = imaging.Rotate90(img)
	images[2] = imaging.Rotate180(img)
	images[3] = imaging.Rotate270(img)
	images[4] = imaging.FlipH(img)
	images[5] = imaging.Rotate90(images[4])
	images[6] = imaging.Rotate180(images[4])
	images[7] = imaging.Rotate270(images[4])

	found := false
	firstHash := uint64(0)
	for i := 0; i < 8; i++ {
		hash := Hash(images[i])
		if i == 0 {
			firstHash = hash
		}

		if _, ok := p.protoImages[hash]; ok {
			found = true
			p.orientations[index] = byte(i)
			p.images[index] = hash
			break
		}
	}

	if !found {
		p.protoImages[firstHash] = img
		p.images[index] = firstHash
		p.orientations[index] = byte(0)
	}
}
示例#4
0
文件: process.go 项目: spideynn/imgd
// Sets skin.Processed to an isometric render of the head from a top-left angle (showing 3 sides).
func (skin *mcSkin) GetCube(width int) error {
	// Crop out the top of the head
	topFlat := imaging.Crop(skin.Image, image.Rect(8, 0, 16, 8))
	// Resize appropriately, so that it fills the `width` when rotated 45 def.
	topFlat = imaging.Resize(topFlat, int(float64(width)*math.Sqrt(2)/3+1), 0, imaging.NearestNeighbor)
	// Create the Gift filter
	filter := gift.New(
		gift.Rotate(45, color.Transparent, gift.LinearInterpolation),
	)
	bounds := filter.Bounds(topFlat.Bounds())
	top := image.NewNRGBA(bounds)
	// Draw it on the filter, then smush it!
	filter.Draw(top, topFlat)
	top = imaging.Resize(top, width+2, width/3, imaging.NearestNeighbor)
	// Skew the front and sides at 15 degree angles to match up with the
	// head that has been smushed
	front := skin.cropHead(skin.Image).(*image.NRGBA)
	side := imaging.Crop(skin.Image, image.Rect(0, 8, 8, 16))
	front = imaging.Resize(front, width/2, int(float64(width)/1.75), imaging.NearestNeighbor)
	side = imaging.Resize(side, width/2, int(float64(width)/1.75), imaging.NearestNeighbor)
	front = skewVertical(front, math.Pi/12)
	side = skewVertical(imaging.FlipH(side), math.Pi/-12)

	// Create a new image to assemble upon
	skin.Processed = image.NewNRGBA(image.Rect(0, 0, width, width))
	// Draw each side
	draw.Draw(skin.Processed.(draw.Image), image.Rect(0, width/6, width/2, width), side, image.Pt(0, 0), draw.Src)
	draw.Draw(skin.Processed.(draw.Image), image.Rect(width/2, width/6, width, width), front, image.Pt(0, 0), draw.Src)
	// Draw the top we created
	draw.Draw(skin.Processed.(draw.Image), image.Rect(-1, 0, width+1, width/3), top, image.Pt(0, 0), draw.Over)

	return nil
}
示例#5
0
// transformImage modifies the image m based on the transformations specified
// in opt.
func transformImage(m image.Image, opt Options) image.Image {
	// resize if needed
	if w, h, resize := resizeParams(m, opt); resize {
		if opt.Fit {
			m = imaging.Fit(m, w, h, resampleFilter)
		} else {
			if w == 0 || h == 0 {
				m = imaging.Resize(m, w, h, resampleFilter)
			} else {
				m = imaging.Thumbnail(m, w, h, resampleFilter)
			}
		}
	}

	// flip
	if opt.FlipVertical {
		m = imaging.FlipV(m)
	}
	if opt.FlipHorizontal {
		m = imaging.FlipH(m)
	}

	// rotate
	switch opt.Rotate {
	case 90:
		m = imaging.Rotate90(m)
	case 180:
		m = imaging.Rotate180(m)
	case 270:
		m = imaging.Rotate270(m)
	}

	return m
}
示例#6
0
文件: util.go 项目: rwcarlsen/gallery
func MakeThumb(r io.Reader, w, h int, orient int) ([]byte, error) {
	img, _, err := image.Decode(r)
	if err != nil {
		return nil, err
	}

	m := resize.Resize(uint(w), uint(h), img, resize.Bicubic)

	switch orient {
	case 3, 4:
		m = imaging.Rotate180(m)
	case 5, 6:
		m = imaging.Rotate270(m)
	case 7, 8:
		m = imaging.Rotate90(m)
	}

	switch orient {
	case 2, 5, 4, 7:
		m = imaging.FlipH(m)
	}

	var buf bytes.Buffer
	err = jpeg.Encode(&buf, m, nil)
	if err != nil {
		return nil, err
	}
	return buf.Bytes(), nil
}
示例#7
0
文件: thumbnail.go 项目: zqzca/back
func rotate(img image.Image, orientation int) image.Image {
	fmt.Println("orientation:", orientation)
	// 1        2       3      4         5            6           7          8

	// 888888  888888      88  88      8888888888  88                  88  8888888888
	// 88          88      88  88      88  88      88  88          88  88      88  88
	// 8888      8888    8888  8888    88          8888888888  8888888888          88
	// 88          88      88  88
	// 88          88  888888  888888

	// func Rotate180(img image.Image) *image.NRGBA
	// func Rotate270(img image.Image) *image.NRGBA
	// func Rotate90(img image.Image) *image.NRGBA
	// func FlipH(img image.Image) *image.NRGBA
	// func FlipV(img image.Image) *image.NRGBA

	var out image.Image
	switch orientation {
	case 1:
		out = img
		// nothing;
	case 2:
		out = imaging.FlipH(img)
		// flip Horiz L to R
	case 3:
		out = imaging.Rotate180(img)
		// rotate 180 ccw
	case 4:
		out = imaging.FlipV(img)
		// flip Vert T to B
	case 5:
		out = imaging.Transpose(img)
		// transpose
	case 6:
		out = imaging.Rotate90(img)
		// rotate 90
	case 7:
		out = imaging.Transverse(img)
		// transverse
	case 8:
		out = imaging.Rotate270(img)
		// rotate 270
	default:
		out = img
		// nothing;
	}

	return out
}
示例#8
0
文件: process.go 项目: spideynn/imgd
// Returns the legs.
func (skin *mcSkin) renderLowerBody() *image.NRGBA {
	// This will be the base.
	lowerBodyImg := image.NewNRGBA(image.Rect(0, 0, LlWidth+RlWidth, LlHeight))

	rlImg := imaging.Crop(skin.Image, image.Rect(RlX, RlY, RlX+RlWidth, RlY+RlHeight))

	// If it's an old skin, they don't have a Left Leg, so we'll just flip their right.
	var llImg image.Image
	if skin.is18Skin() {
		llImg = imaging.Crop(skin.Image, image.Rect(LlX, LlY, LlX+LlWidth, LlY+LlHeight))
	} else {
		llImg = imaging.FlipH(rlImg)
	}

	return skin.drawLower(lowerBodyImg, rlImg, llImg.(*image.NRGBA))
}
示例#9
0
func handleImages(previewPathList []string, thumbnailPathList []string, fileData [][]byte) {
	for i, data := range fileData {
		go func(i int, data []byte) {
			// Decode image bytes into Image object
			img, imgType, err := image.Decode(bytes.NewReader(fileData[i]))
			if err != nil {
				l4g.Error(utils.T("api.file.handle_images_forget.decode.error"), err)
				return
			}

			width := img.Bounds().Dx()
			height := img.Bounds().Dy()

			// Fill in the background of a potentially-transparent png file as white
			if imgType == "png" {
				dst := image.NewRGBA(img.Bounds())
				draw.Draw(dst, dst.Bounds(), image.NewUniform(color.White), image.Point{}, draw.Src)
				draw.Draw(dst, dst.Bounds(), img, img.Bounds().Min, draw.Over)
				img = dst
			}

			// Flip the image to be upright
			orientation, _ := getImageOrientation(fileData[i])

			switch orientation {
			case UprightMirrored:
				img = imaging.FlipH(img)
			case UpsideDown:
				img = imaging.Rotate180(img)
			case UpsideDownMirrored:
				img = imaging.FlipV(img)
			case RotatedCWMirrored:
				img = imaging.Transpose(img)
			case RotatedCCW:
				img = imaging.Rotate270(img)
			case RotatedCCWMirrored:
				img = imaging.Transverse(img)
			case RotatedCW:
				img = imaging.Rotate90(img)
			}

			go generateThumbnailImage(img, thumbnailPathList[i], width, height)
			go generatePreviewImage(img, previewPathList[i], width)
		}(i, data)
	}
}
示例#10
0
文件: process.go 项目: spideynn/imgd
// Returns the torso and arms.
func (skin *mcSkin) renderUpperBody() *image.NRGBA {
	// This will be the base.
	upperBodyImg := image.NewNRGBA(image.Rect(0, 0, LaWidth+TorsoWidth+RaWidth, TorsoHeight))

	torsoImg := imaging.Crop(skin.Image, image.Rect(TorsoX, TorsoY, TorsoX+TorsoWidth, TorsoY+TorsoHeight))
	raImg := imaging.Crop(skin.Image, image.Rect(RaX, RaY, RaX+RaWidth, RaY+TorsoHeight))

	// If it's an old skin, they don't have a Left Arm, so we'll just flip their right.
	var laImg image.Image
	if skin.is18Skin() {
		laImg = imaging.Crop(skin.Image, image.Rect(LaX, LaY, LaX+LaWidth, LaY+TorsoHeight))
	} else {
		laImg = imaging.FlipH(raImg)
	}

	return skin.drawUpper(upperBodyImg, torsoImg, raImg, laImg.(*image.NRGBA))
}
示例#11
0
文件: process.go 项目: spideynn/imgd
func skewVertical(src *image.NRGBA, degrees float64) *image.NRGBA {
	bounds := src.Bounds()
	maxY := bounds.Max.Y
	maxX := bounds.Max.X * 4
	distance := float64(bounds.Max.X) * math.Tan(degrees)
	shouldFlip := false
	if distance < 0 {
		distance = -distance
		shouldFlip = true
	}

	newHeight := maxY + int(1+distance)
	dst := image.NewNRGBA(image.Rect(0, 0, bounds.Max.X, newHeight))

	step := distance
	for x := 0; x < maxX; x += 4 {
		for row := 0; row < maxY; row += 1 {
			srcPx := row*src.Stride + x
			dstLower := (int(step)+row)*dst.Stride + x
			dstUpper := dstLower + dst.Stride
			_, delta := math.Modf(step)

			if src.Pix[srcPx+3] != 0 {
				dst.Pix[dstLower+0] += uint8(float64(src.Pix[srcPx+0]) * (1 - delta))
				dst.Pix[dstLower+1] += uint8(float64(src.Pix[srcPx+1]) * (1 - delta))
				dst.Pix[dstLower+2] += uint8(float64(src.Pix[srcPx+2]) * (1 - delta))
				dst.Pix[dstLower+3] += uint8(float64(src.Pix[srcPx+3]) * (1 - delta))

				dst.Pix[dstUpper+0] += uint8(float64(src.Pix[srcPx+0]) * delta)
				dst.Pix[dstUpper+1] += uint8(float64(src.Pix[srcPx+1]) * delta)
				dst.Pix[dstUpper+2] += uint8(float64(src.Pix[srcPx+2]) * delta)
				dst.Pix[dstUpper+3] += uint8(float64(src.Pix[srcPx+3]) * delta)
			}
		}

		step -= distance / float64(bounds.Max.X)
	}

	if shouldFlip {
		return imaging.FlipH(dst)
	} else {
		return dst
	}
}
示例#12
0
文件: file.go 项目: Rudloff/platform
func prepareImage(fileData []byte) (*image.Image, int, int) {
	// Decode image bytes into Image object
	img, imgType, err := image.Decode(bytes.NewReader(fileData))
	if err != nil {
		l4g.Error(utils.T("api.file.handle_images_forget.decode.error"), err)
		return nil, 0, 0
	}

	width := img.Bounds().Dx()
	height := img.Bounds().Dy()

	// Fill in the background of a potentially-transparent png file as white
	if imgType == "png" {
		dst := image.NewRGBA(img.Bounds())
		draw.Draw(dst, dst.Bounds(), image.NewUniform(color.White), image.Point{}, draw.Src)
		draw.Draw(dst, dst.Bounds(), img, img.Bounds().Min, draw.Over)
		img = dst
	}

	// Flip the image to be upright
	orientation, _ := getImageOrientation(fileData)

	switch orientation {
	case UprightMirrored:
		img = imaging.FlipH(img)
	case UpsideDown:
		img = imaging.Rotate180(img)
	case UpsideDownMirrored:
		img = imaging.FlipV(img)
	case RotatedCWMirrored:
		img = imaging.Transpose(img)
	case RotatedCCW:
		img = imaging.Rotate270(img)
	case RotatedCCWMirrored:
		img = imaging.Transverse(img)
	case RotatedCW:
		img = imaging.Rotate90(img)
	}

	return &img, width, height
}
示例#13
0
// Transforms image (resize, rotate, flip, brightness, contrast)
func (c *Convertor) TransformImage(img image.Image) image.Image {
	var i image.Image = img

	if c.Opts.Width > 0 || c.Opts.Height > 0 {
		if c.Opts.Fit {
			i = imaging.Fit(i, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter])
		} else {
			i = imaging.Resize(i, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter])
		}
	}

	if c.Opts.Rotate > 0 {
		switch c.Opts.Rotate {
		case 90:
			i = imaging.Rotate90(i)
		case 180:
			i = imaging.Rotate180(i)
		case 270:
			i = imaging.Rotate270(i)
		}
	}

	if c.Opts.Flip != "none" {
		switch c.Opts.Flip {
		case "horizontal":
			i = imaging.FlipH(i)
		case "vertical":
			i = imaging.FlipV(i)
		}
	}

	if c.Opts.Brightness != 0 {
		i = imaging.AdjustBrightness(i, c.Opts.Brightness)
	}

	if c.Opts.Contrast != 0 {
		i = imaging.AdjustContrast(i, c.Opts.Contrast)
	}

	return i
}
示例#14
0
func storeImage(rw http.ResponseWriter, req *http.Request) {
	// Appengine
	var c appengine.Context
	// Google Cloud Storage authentication
	var cc gcscontext.Context
	// Google Cloud Storage bucket name
	var bucketName string = ""
	// Google Cloud Storage client
	var client *storage.Client
	// Google Cloud Storage bucket
	var bucketHandle *storage.BucketHandle
	// User uploaded image file name
	var fileName string = uuid.New()
	// Transform user uploaded image to a thumbnail file name
	var fileNameThumbnail string = uuid.New()
	// User uploaded image file type
	var contentType string = ""
	// User uploaded image file raw data
	var b []byte
	// Google Cloud Storage file writer
	var wc *storage.Writer = nil
	// Error
	var err error = nil
	// Result, 0: success, 1: failed
	var r int = http.StatusCreated

	// Set response in the end
	defer func() {
		// Return status. WriteHeader() must be called before call to Write
		if r == http.StatusCreated {
			// Changing the header after a call to WriteHeader (or Write) has no effect.
			// rw.Header().Set("Location", req.URL.String()+"/"+cKey.Encode())
			rw.Header().Set("Location", "http://"+bucketName+".storage.googleapis.com/"+fileName)
			rw.Header().Set("X-Thumbnail", "http://"+bucketName+".storage.googleapis.com/"+fileNameThumbnail)
			rw.WriteHeader(r)
		} else {
			http.Error(rw, http.StatusText(r), r)
		}
	}()

	// To log information in Google APP Engine console
	c = appengine.NewContext(req)

	// Get data from body
	b, err = ioutil.ReadAll(req.Body)
	if err != nil {
		c.Errorf("%s in reading body", err)
		r = http.StatusInternalServerError
		return
	}
	c.Infof("Body length %d bytes, read %d bytes", req.ContentLength, len(b))

	// Determine filename extension from content type
	contentType = req.Header["Content-Type"][0]
	switch contentType {
	case "image/jpeg":
		fileName += ".jpg"
		fileNameThumbnail += ".jpg"
	default:
		c.Errorf("Unknown or unsupported content type '%s'. Valid: image/jpeg", contentType)
		r = http.StatusBadRequest
		return
	}
	c.Infof("Content type %s is received, %s is detected.", contentType, http.DetectContentType(b))

	// Prepare Google Cloud Storage authentication
	cc = gcsappengine.NewContext(req)
	if client, err = storage.NewClient(cc); err != nil {
		c.Errorf("%s in initializing a GCS client", err)
		r = http.StatusInternalServerError
		return
	}
	defer client.Close()

	// Get default bucket
	if bucketName, err = gcsfile.DefaultBucketName(cc); err != nil {
		c.Errorf("%s in getting default GCS bucket name", err)
		r = http.StatusInternalServerError
		return
	}
	bucketHandle = client.Bucket(bucketName)
	c.Infof("APP Engine Version: %s", gcsappengine.VersionID(cc))
	c.Infof("Using bucket name: %s", bucketName)

	// Change default object ACLs
	if err = bucketHandle.DefaultObjectACL().Set(cc, storage.AllUsers, storage.RoleReader); err != nil {
		c.Errorf("%v in saving default object ACL rule for bucket %q", err, bucketName)
		r = http.StatusInternalServerError
		return
	}

	// Store rotated image in Google Cloud Storage
	var in *bytes.Reader = bytes.NewReader(b)
	var x *exif.Exif = nil
	var orientation *tiff.Tag = nil
	var beforeImage image.Image
	var afterImage *image.NRGBA = nil

	// Read EXIF
	if _, err = in.Seek(0, 0); err != nil {
		c.Errorf("%s in moving the reader offset to the beginning in order to read EXIF", err)
		return
	}
	if x, err = exif.Decode(in); err != nil {
		c.Errorf("%s in decoding JPEG image", err)
		return
	}

	// Get Orientation
	if orientation, err = x.Get(exif.Orientation); err != nil {
		c.Warningf("%s in getting orientation from EXIF", err)
		return
	}
	c.Debugf("Orientation %s", orientation.String())

	// Open image
	if _, err = in.Seek(0, 0); err != nil {
		c.Errorf("%s in moving the reader offset to the beginning in order to read EXIF", err)
		return
	}
	if beforeImage, err = imaging.Decode(in); err != nil {
		c.Errorf("%s in opening image %s", err)
		return
	}

	switch orientation.String() {
	case "1":
		afterImage = beforeImage.(*image.NRGBA)
	case "2":
		afterImage = imaging.FlipH(beforeImage)
	case "3":
		afterImage = imaging.Rotate180(beforeImage)
	case "4":
		afterImage = imaging.FlipV(beforeImage)
	case "5":
		afterImage = imaging.Transverse(beforeImage)
	case "6":
		afterImage = imaging.Rotate270(beforeImage)
	case "7":
		afterImage = imaging.Transpose(beforeImage)
	case "8":
		afterImage = imaging.Rotate90(beforeImage)
	}

	// Save rotated image
	wc = bucketHandle.Object(fileName).NewWriter(cc)
	wc.ContentType = contentType
	if err = imaging.Encode(wc, afterImage, imaging.JPEG); err != nil {
		c.Errorf("%s in saving rotated image", err)
		return
	}
	if err = wc.Close(); err != nil {
		c.Errorf("CreateFile: unable to close bucket %q, file %q: %v", bucketName, fileName, err)
		r = 1
		return
	}
	wc = nil

	// Make thumbnail
	if afterImage.Rect.Dx() > afterImage.Rect.Dy() {
		afterImage = imaging.Resize(afterImage, 1920, 0, imaging.Lanczos)
	} else {
		afterImage = imaging.Resize(afterImage, 0, 1920, imaging.Lanczos)
	}

	// Save thumbnail
	wc = bucketHandle.Object(fileNameThumbnail).NewWriter(cc)
	wc.ContentType = contentType
	if imaging.Encode(wc, afterImage, imaging.JPEG); err != nil {
		c.Errorf("%s in saving image thumbnail", err)
		return
	}
	if err = wc.Close(); err != nil {
		c.Errorf("CreateFileThumbnail: unable to close bucket %q, file %q: %v", bucketName, fileNameThumbnail, err)
		r = 1
		return
	}

	c.Infof("/%v/%v, /%v/%v created", bucketName, fileName, bucketName, fileNameThumbnail)
}
示例#15
0
// transformImage modifies the image m based on the transformations specified
// in opt.
func transformImage(m image.Image, opt Options) image.Image {
	// convert percentage width and height values to absolute values
	imgW := m.Bounds().Max.X - m.Bounds().Min.X
	imgH := m.Bounds().Max.Y - m.Bounds().Min.Y
	var w, h int
	if 0 < opt.Width && opt.Width < 1 {
		w = int(float64(imgW) * opt.Width)
	} else if opt.Width < 0 {
		w = 0
	} else {
		w = int(opt.Width)
	}
	if 0 < opt.Height && opt.Height < 1 {
		h = int(float64(imgH) * opt.Height)
	} else if opt.Height < 0 {
		h = 0
	} else {
		h = int(opt.Height)
	}

	// never resize larger than the original image
	if !opt.ScaleUp {
		if w > imgW {
			w = imgW
		}
		if h > imgH {
			h = imgH
		}
	}

	// resize
	if w != 0 || h != 0 {
		if opt.Fit {
			m = imaging.Fit(m, w, h, resampleFilter)
		} else {
			if w == 0 || h == 0 {
				m = imaging.Resize(m, w, h, resampleFilter)
			} else {
				m = imaging.Thumbnail(m, w, h, resampleFilter)
			}
		}
	}

	// flip
	if opt.FlipVertical {
		m = imaging.FlipV(m)
	}
	if opt.FlipHorizontal {
		m = imaging.FlipH(m)
	}

	// rotate
	switch opt.Rotate {
	case 90:
		m = imaging.Rotate90(m)
	case 180:
		m = imaging.Rotate180(m)
	case 270:
		m = imaging.Rotate270(m)
	}

	return m
}
示例#16
0
文件: flipper.go 项目: manyminds/tmx
func (i imagingFlipper) FlipDiagonal(tile image.Image) image.Image {
	return imaging.FlipH(imaging.Rotate270(tile))
}
示例#17
0
文件: flipper.go 项目: manyminds/tmx
func (i imagingFlipper) FlipHorizontal(tile image.Image) image.Image {
	return imaging.FlipH(tile)
}
示例#18
0
func main() {
	resources := make(ResourceMap)
	constants := bytes.NewBuffer(nil)

	gophette, err := xcf.LoadFromFile("./gophette.xcf")
	check(err)
	barney, err := xcf.LoadFromFile("./barney.xcf")
	check(err)

	// create the collision information for Gophette and Barney
	addCollisionInfo := func(canvas xcf.Canvas, variable string) {
		collision := canvas.GetLayerByName("collision")
		left, top := findTopLeftNonTransparentPixel(collision)
		right, bottom := findBottomRightNonTransparentPixel(collision)
		// scale the collision rect just like the images
		left = int(0.5 + scale*float64(left))
		top = int(0.5 + scale*float64(top))
		right = int(0.5 + scale*float64(right))
		bottom = int(0.5 + scale*float64(bottom))
		width, height := right-left+1, bottom-top+1
		line := fmt.Sprintf(
			"var %v = Rectangle{%v, %v, %v, %v}\n",
			variable,
			left, top, width, height,
		)
		constants.WriteString(line)
	}
	addCollisionInfo(gophette, "HeroCollisionRect")
	addCollisionInfo(barney, "BarneyCollisionRect")

	// create the image resources
	for _, layer := range []string{
		"jump",
		"run1",
		"run2",
		"run3",
	} {
		small := scaleImage(gophette.GetLayerByName(layer))
		resources["gophette_left_"+layer] = imageToBytes(small)
		resources["gophette_right_"+layer] = imageToBytes(imaging.FlipH(small))
	}

	for _, layer := range []string{
		"stand",
		"jump",
		"run1",
		"run2",
		"run3",
		"run4",
		"run5",
		"run6",
	} {
		smallLeft := scaleImage(barney.GetLayerByName("left_" + layer))
		smallRight := scaleImage(barney.GetLayerByName("right_" + layer))
		resources["barney_left_"+layer] = imageToBytes(smallLeft)
		resources["barney_right_"+layer] = imageToBytes(smallRight)
	}

	grass, err := xcf.LoadFromFile("./grass.xcf")
	check(err)
	for _, layer := range []string{
		"grass left",
		"grass right",
		"grass center 1",
		"grass center 2",
		"grass center 3",
	} {
		resources[layer] = imageToBytes(grass.GetLayerByName(layer))
	}

	grassLong, err := xcf.LoadFromFile("./grass_long.xcf")
	check(err)
	for _, layer := range []string{
		"grass long 1",
		"grass long 2",
		"grass long 3",
	} {
		resources[layer] = imageToBytes(grassLong.GetLayerByName(layer))
	}

	ground, err := xcf.LoadFromFile("./ground.xcf")
	check(err)
	for _, layer := range []string{
		"ground left",
		"ground right",
		"ground center 1",
		"ground center 2",
		"ground center 3",
	} {
		resources[layer] = imageToBytes(ground.GetLayerByName(layer))
	}

	groundLong, err := xcf.LoadFromFile("./ground_long.xcf")
	check(err)
	for _, layer := range []string{
		"ground long 1",
		"ground long 2",
	} {
		resources[layer] = imageToBytes(groundLong.GetLayerByName(layer))
	}

	rock, err := xcf.LoadFromFile("./rock.xcf")
	check(err)
	resources["square rock"] = imageToBytes(scaleImage(rock.GetLayerByName("rock")))

	tree, err := xcf.LoadFromFile("./tree.xcf")
	check(err)
	smallTree := scaleImage(tree.GetLayerByName("small"))
	resources["small tree"] = imageToBytes(smallTree)

	tree, err = xcf.LoadFromFile("./tree_big.xcf")
	check(err)
	bigTree := scaleImage(tree.GetLayerByName("big"))
	resources["big tree"] = imageToBytes(bigTree)

	tree, err = xcf.LoadFromFile("./tree_huge.xcf")
	check(err)
	hugeTree := scaleImage(tree.GetLayerByName("huge"))
	resources["huge tree"] = imageToBytes(hugeTree)

	cave, err := xcf.LoadFromFile("./cave.xcf")
	check(err)
	resources["cave back"] = imageToBytes(scaleImage(cave.GetLayerByName("cave back")))
	resources["cave front"] = imageToBytes(scaleImage(cave.GetLayerByName("cave front")))

	intro, err := xcf.LoadFromFile("./intro.xcf")
	check(err)
	resources["intro pc 1"] = imageToBytes(scaleImageToFactor(intro.GetLayerByName("pc 1"), 0.67))
	resources["intro pc 2"] = imageToBytes(scaleImageToFactor(intro.GetLayerByName("pc 2"), 0.67))
	resources["intro gophette"] = imageToBytes(scaleImageToFactor(intro.GetLayerByName("gophette"), 0.67))

	// the music file is too big, breaks IDE
	/*
		music, err := ioutil.ReadFile("./background_music.ogg")
		check(err)
		resources["music"] = music
	*/

	for _, sound := range []string{
		"win",
		"lose",
		"fall",
		"barney wins",
		"barney intro text",
		"whistle",
		"instructions",
	} {
		data, err := ioutil.ReadFile(sound + ".wav")
		check(err)
		resources[sound] = data
	}

	content := toGoFile(resources, string(constants.Bytes()))
	ioutil.WriteFile("../resource/resources.go", content, 0777)
}
示例#19
0
func main() {
	resources := blob.New()
	textureAtlas := atlas.New(2048)

	gophette, err := xcf.LoadFromFile("./gophette.xcf")
	check(err)
	barney, err := xcf.LoadFromFile("./barney.xcf")
	check(err)

	// create the collision information for Gophette and Barney
	addCollisionInfo := func(canvas xcf.Canvas, id string) {
		collision := canvas.GetLayerByName("collision")
		left, top := findTopLeftNonTransparentPixel(collision)
		right, bottom := findBottomRightNonTransparentPixel(collision)
		// scale the collision rect just like the images
		left = int(0.5 + scale*float64(left))
		top = int(0.5 + scale*float64(top))
		right = int(0.5 + scale*float64(right))
		bottom = int(0.5 + scale*float64(bottom))
		width, height := right-left+1, bottom-top+1
		r := rect{int32(left), int32(top), int32(width), int32(height)}
		buffer := bytes.NewBuffer(nil)
		check(binary.Write(buffer, byteOrder, &r))
		resources.Append(id, buffer.Bytes())
	}
	addCollisionInfo(gophette, "hero collision")
	addCollisionInfo(barney, "barney collision")

	addImage := func(img image.Image, id string) {
		_, err := textureAtlas.Add(id, img)
		check(err)
	}

	// create the image resources
	for _, layer := range []string{
		"jump",
		"run1",
		"run2",
		"run3",
	} {
		small := scaleImage(gophette.GetLayerByName(layer))
		addImage(small, "gophette_left_"+layer)
		addImage(imaging.FlipH(small), "gophette_right_"+layer)
	}

	for _, layer := range []string{
		"stand",
		"jump",
		"run1",
		"run2",
		"run3",
		"run4",
		"run5",
		"run6",
	} {
		smallLeft := scaleImage(barney.GetLayerByName("left_" + layer))
		smallRight := scaleImage(barney.GetLayerByName("right_" + layer))
		addImage(smallLeft, "barney_left_"+layer)
		addImage(smallRight, "barney_right_"+layer)
	}

	grass, err := xcf.LoadFromFile("./grass.xcf")
	check(err)
	for _, layer := range []string{
		"grass left",
		"grass right",
		"grass center 1",
		"grass center 2",
		"grass center 3",
	} {
		addImage(grass.GetLayerByName(layer), layer)
	}

	grassLong, err := xcf.LoadFromFile("./grass_long.xcf")
	check(err)
	for _, layer := range []string{
		"grass long 1",
		"grass long 2",
		"grass long 3",
	} {
		addImage(grassLong.GetLayerByName(layer), layer)
	}

	ground, err := xcf.LoadFromFile("./ground.xcf")
	check(err)
	for _, layer := range []string{
		"ground left",
		"ground right",
		"ground center 1",
		"ground center 2",
		"ground center 3",
	} {
		addImage(ground.GetLayerByName(layer), layer)
	}

	groundLong, err := xcf.LoadFromFile("./ground_long.xcf")
	check(err)
	for _, layer := range []string{
		"ground long 1",
		"ground long 2",
	} {
		addImage(groundLong.GetLayerByName(layer), layer)
	}

	rock, err := xcf.LoadFromFile("./rock.xcf")
	check(err)
	addImage(scaleImage(rock.GetLayerByName("rock")), "square rock")

	tree, err := xcf.LoadFromFile("./tree.xcf")
	check(err)
	smallTree := scaleImage(tree.GetLayerByName("small"))
	addImage(smallTree, "small tree")

	tree, err = xcf.LoadFromFile("./tree_big.xcf")
	check(err)
	bigTree := scaleImage(tree.GetLayerByName("big"))
	addImage(bigTree, "big tree")

	tree, err = xcf.LoadFromFile("./tree_huge.xcf")
	check(err)
	hugeTree := scaleImage(tree.GetLayerByName("huge"))
	addImage(hugeTree, "huge tree")

	cave, err := xcf.LoadFromFile("./cave.xcf")
	check(err)
	addImage(scaleImage(cave.GetLayerByName("cave back")), "cave back")
	addImage(scaleImage(cave.GetLayerByName("cave front")), "cave front")

	intro, err := xcf.LoadFromFile("./intro.xcf")
	check(err)
	addImage(scaleImageToFactor(intro.GetLayerByName("pc 1"), 0.67), "intro pc 1")
	addImage(scaleImageToFactor(intro.GetLayerByName("pc 2"), 0.67), "intro pc 2")
	addImage(scaleImageToFactor(intro.GetLayerByName("gophette"), 0.67), "intro gophette")

	{
		music, err := ioutil.ReadFile("./background_music.ogg")
		check(err)
		resources.Append("music", music)
	}

	{
		music, err := ioutil.ReadFile("./background_music.wav")
		check(err)
		resources.Append("music_wav", music)
	}

	for _, sound := range []string{
		"win",
		"lose",
		"fall",
		"barney wins",
		"barney intro text",
		"whistle",
		"instructions",
	} {
		data, err := ioutil.ReadFile(sound + ".wav")
		check(err)
		resources.Append(sound, data)
	}

	resources.Append("atlas", imageToBytes(textureAtlas))
	for _, sub := range textureAtlas.SubImages {
		resources.Append(
			sub.ID,
			toRectData(sub.Bounds().Sub(textureAtlas.Bounds().Min)),
		)
	}

	resourceFile, err := os.Create("../resource/resources.blob")
	check(err)
	defer resourceFile.Close()
	resources.Write(resourceFile)
}
示例#20
0
func handleImages(filenames []string, fileData [][]byte, teamId, channelId, userId string) {
	dest := "teams/" + teamId + "/channels/" + channelId + "/users/" + userId + "/"

	for i, filename := range filenames {
		name := filename[:strings.LastIndex(filename, ".")]
		go func() {
			// Decode image bytes into Image object
			img, imgType, err := image.Decode(bytes.NewReader(fileData[i]))
			if err != nil {
				l4g.Error(utils.T("api.file.handle_images_forget.decode.error"), channelId, userId, filename, err)
				return
			}

			width := img.Bounds().Dx()
			height := img.Bounds().Dy()

			// Get the image's orientation and ignore any errors since not all images will have orientation data
			orientation, _ := getImageOrientation(fileData[i])

			if imgType == "png" {
				dst := image.NewRGBA(img.Bounds())
				draw.Draw(dst, dst.Bounds(), image.NewUniform(color.White), image.Point{}, draw.Src)
				draw.Draw(dst, dst.Bounds(), img, img.Bounds().Min, draw.Over)
				img = dst
			}

			switch orientation {
			case UprightMirrored:
				img = imaging.FlipH(img)
			case UpsideDown:
				img = imaging.Rotate180(img)
			case UpsideDownMirrored:
				img = imaging.FlipV(img)
			case RotatedCWMirrored:
				img = imaging.Transpose(img)
			case RotatedCCW:
				img = imaging.Rotate270(img)
			case RotatedCCWMirrored:
				img = imaging.Transverse(img)
			case RotatedCW:
				img = imaging.Rotate90(img)
			}

			// Create thumbnail
			go func() {
				thumbWidth := float64(utils.Cfg.FileSettings.ThumbnailWidth)
				thumbHeight := float64(utils.Cfg.FileSettings.ThumbnailHeight)
				imgWidth := float64(width)
				imgHeight := float64(height)

				var thumbnail image.Image
				if imgHeight < thumbHeight && imgWidth < thumbWidth {
					thumbnail = img
				} else if imgHeight/imgWidth < thumbHeight/thumbWidth {
					thumbnail = imaging.Resize(img, 0, utils.Cfg.FileSettings.ThumbnailHeight, imaging.Lanczos)
				} else {
					thumbnail = imaging.Resize(img, utils.Cfg.FileSettings.ThumbnailWidth, 0, imaging.Lanczos)
				}

				buf := new(bytes.Buffer)
				err = jpeg.Encode(buf, thumbnail, &jpeg.Options{Quality: 90})
				if err != nil {
					l4g.Error(utils.T("api.file.handle_images_forget.encode_jpeg.error"), channelId, userId, filename, err)
					return
				}

				if err := WriteFile(buf.Bytes(), dest+name+"_thumb.jpg"); err != nil {
					l4g.Error(utils.T("api.file.handle_images_forget.upload_thumb.error"), channelId, userId, filename, err)
					return
				}
			}()

			// Create preview
			go func() {
				var preview image.Image
				if width > int(utils.Cfg.FileSettings.PreviewWidth) {
					preview = imaging.Resize(img, utils.Cfg.FileSettings.PreviewWidth, utils.Cfg.FileSettings.PreviewHeight, imaging.Lanczos)
				} else {
					preview = img
				}

				buf := new(bytes.Buffer)

				err = jpeg.Encode(buf, preview, &jpeg.Options{Quality: 90})
				if err != nil {
					l4g.Error(utils.T("api.file.handle_images_forget.encode_preview.error"), channelId, userId, filename, err)
					return
				}

				if err := WriteFile(buf.Bytes(), dest+name+"_preview.jpg"); err != nil {
					l4g.Error(utils.T("api.file.handle_images_forget.upload_preview.error"), channelId, userId, filename, err)
					return
				}
			}()
		}()
	}
}
示例#21
0
func main() {
	fmt.Println("Hello, world")
	fname := "P1070332.JPG"
	rname := "P1070332_rotate.JPG"
	sname := "P1070332_small.JPG"

	f, err := os.Open(fname)
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()

	// Optionally register camera makenote data parsing - currently Nikon and
	// Canon are supported.
	exif.RegisterParsers(mknote.All...)

	x, err := exif.Decode(f)
	if err != nil {
		log.Fatal(err)
	}

	// Get Orientation
	orientation, err := x.Get(exif.Orientation)
	if err != nil {
		fmt.Println(exif.Model, " not fround")
		return
	}
	fmt.Println("Orientation", orientation.String())

	// Rotate
	var rotateImage *image.NRGBA
	openImage, err := imaging.Open(fname)
	if err != nil {
		fmt.Println(err)
		return
	}
	switch orientation.String() {
	case "1":
	// Do nothing
	case "2":
		rotateImage = imaging.FlipH(openImage)
	case "3":
		rotateImage = imaging.Rotate180(openImage)
	case "4":
		rotateImage = imaging.FlipV(openImage)
	case "5":
		rotateImage = imaging.Transverse(openImage)
	case "6":
		rotateImage = imaging.Rotate270(openImage)
	case "7":
		rotateImage = imaging.Transpose(openImage)
	case "8":
		rotateImage = imaging.Rotate90(openImage)
	}
	err = imaging.Save(rotateImage, rname)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(rname, " saved")

	// Small
	var smallImage *image.NRGBA
	if rotateImage.Rect.Dx() > rotateImage.Rect.Dy() {
		smallImage = imaging.Resize(rotateImage, 1920, 0, imaging.Lanczos)
	} else {
		smallImage = imaging.Resize(rotateImage, 0, 1920, imaging.Lanczos)
	}
	err = imaging.Save(smallImage, sname)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(sname, " saved")

	// Use jpeg.Encode() to write to a file
	// https://github.com/disintegration/imaging/blob/master/helpers.go#L79
	// func Encode(w io.Writer, m image.Image, o *Options) error
	// https://golang.org/pkg/image/jpeg/
}