//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 }
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 }
// 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) } }
// 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 }
// 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 }
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 }
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 }
// 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)) }
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) } }
// 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)) }
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 } }
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 }
// 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 }
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) }
// 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 }
func (i imagingFlipper) FlipDiagonal(tile image.Image) image.Image { return imaging.FlipH(imaging.Rotate270(tile)) }
func (i imagingFlipper) FlipHorizontal(tile image.Image) image.Image { return imaging.FlipH(tile) }
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) }
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) }
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 } }() }() } }
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/ }