func createThumbPic(source, to string, width, height uint) error { source_file, err := os.Open(source) if err != nil { return err } defer source_file.Close() thumb_pic, err := os.Create(to) if err != nil { return err } defer thumb_pic.Close() // decode jpeg into image.Image img, err := jpeg.Decode(source_file) if err != nil { return err } // resize to width 1000 using Lanczos resampling // and preserve aspect ratio m := resize.Thumbnail(width, height, img, resize.Lanczos3) // write new image to file if err := jpeg.Encode(thumb_pic, m, nil); err != nil { return err } return nil }
func resizeImage(inDir string, name string, size uint, outDir string) { file, err := os.Open(inDir + name) if err != nil { log.Fatal(err) } // decode jpeg into image.Image img, err := jpeg.Decode(file) if err != nil { log.Fatal(err) } file.Close() // resize to width 1000 using Lanczos resampling // and preserve aspect ratio m := resize.Thumbnail(size, size, img, resize.Lanczos3) out, err := os.Create(outDir + name) if err != nil { log.Fatal(err) } defer out.Close() // write new image to file jpeg.Encode(out, m, nil) }
//Save a User Avatar Image func (uam *UserAvatarManager) SaveImage(id string, rev string, attType string, data io.Reader, curUser *CurrentUserInfo) (string, error) { auth := curUser.Auth // Decode the image image, _, err := image.Decode(data) if err != nil { return "", err } // We need two image sizes, 200px, and a 32px thumbnail largeSize := resize.Resize(200, 0, image, resize.Bicubic) lRev, err := uam.saveImage(id, rev, "largeSize", largeSize, auth) if err != nil { return "", err } thumbnail := resize.Thumbnail(32, 32, image, resize.Bicubic) tRev, err := uam.saveImage(id, lRev, "thumbnail", thumbnail, auth) if err != nil { return "", err } um := new(UserManager) user := User{} uRev, err := um.Read(id, &user, curUser) if err != nil { return "", err } theUri := services.ApiPrefix() + "/users" + avatarUri user.Public.Avatar = strings.Replace(theUri+"/image", "{user-id}", id, 1) user.Public.AvatarThumbnail = strings.Replace(theUri+"/thumbnail", "{user-id}", id, 1) if uRev, err = um.Update(id, uRev, &user, curUser); err != nil { return "", err } else { return tRev, nil } }
func imageResize(filePath, newFilePath string, width, height uint, interp resize.InterpolationFunction) error { imgb, err := os.Open(filePath) if err != nil { return err } defer imgb.Close() img, _, err := image.Decode(imgb) if err != nil { return err } m := resize.Thumbnail(width, height, img, interp) out, err := os.Create(newFilePath) if err != nil { return err } defer out.Close() // write new image to file jpeg.Encode(out, m, nil) return nil }
func main() { flag.Parse() imgs := flag.Args() if len(imgs) == 0 { fmt.Printf("usage: %s imagefile ...\n", os.Args[0]) flag.PrintDefaults() os.Exit(1) } for _, i := range imgs { img, err := openImage(i) if err != nil { panic(err) } t := resize.Thumbnail(*flagBox, *flagBox, img, resampler(*flagResampling)) out, err := os.Create(outName(i)) if err != nil { panic(err) } err = png.Encode(out, t) if err != nil { panic(err) } out.Close() } }
// Make thumbnail for the selected file func MakeThumb(src string, dst_sane string, dst_thumb string) error { file, err := os.Open(src) defer file.Close() if err != nil { return err } img, err := jpeg.Decode(file) if err != nil { return err } sane := resize.Resize(1080, 0, img, resize.Bilinear) out_sane, err := os.Create(dst_sane) if err != nil { return err } defer out_sane.Close() jpeg.Encode(out_sane, sane, nil) thumb := resize.Thumbnail(200, 200, img, resize.Bilinear) out_thumb, err := os.Create(dst_thumb) if err != nil { return err } defer out_thumb.Close() jpeg.Encode(out_thumb, thumb, nil) return nil }
func generateThumbnail(source, destination string) error { file, err := os.Open(source) if err != nil { return err } var img image.Image var imageType string img, imageType, err = image.Decode(file) if err != nil { return err } file.Close() m := resize.Thumbnail(maxWidth, maxHeight, img, resize.Lanczos3) out, err := os.Create(destination) if err != nil { return err } defer out.Close() switch imageType { case "gif": return gif.Encode(out, m, nil) case "jpeg": return jpeg.Encode(out, m, nil) case "png": return png.Encode(out, m) } return nil }
func printImage(img image.Image, width uint, height uint) { resized := resize.Thumbnail(width, height, img, resize.NearestNeighbor) bounds := resized.Bounds() for y := bounds.Min.Y; y < bounds.Max.Y; y += 2 { for x := bounds.Min.X; x < bounds.Max.X; x++ { upperRed, upperGreen, upperBlue, _ := resized.At(x, y).RGBA() lowerRed, lowerGreen, lowerBlue, _ := resized.At(x, y+1).RGBA() // Only print the background if upper and lower row are same color if upperRed == lowerRed && upperGreen == lowerGreen && upperBlue == lowerBlue { fmt.Printf( "\x1b[48;2;%d;%d;%dm ", upperRed/256, upperGreen/256, upperBlue/256, ) } else { fmt.Printf( "\x1b[48;2;%d;%d;%dm\x1b[38;2;%d;%d;%dm▄", upperRed/256, upperGreen/256, upperBlue/256, lowerRed/256, lowerGreen/256, lowerBlue/256, ) } } fmt.Println("\x1b[0m") } }
// cropImage permet de redimensionnement d'une image // @todo il faut permettre le crop de jpg, png et gif // pour le moment la fonction permet de réaliser des crop uniquemen pour des jpeg func CropImage(imageUrl string, toW uint, toH uint) error { // open file rfile, err := os.Open(imageUrl) defer rfile.Close() if err != nil { return errors.New("le fichier n' a pas les droits pour être ouvert") } // decode jpeg into image.Image rimg, err := jpeg.Decode(rfile) if err != nil { return errors.New("l'image n'a pas put être décodé") } //rfile.Close() image := resize.Thumbnail(toW, toH, rimg, resize.Bilinear) out, err := os.Create(imageUrl) defer out.Close() if err != nil { return errors.New("l'image n'a pas put être créé") } // write new image to file jpeg.Encode(out, image, nil) return nil }
func generateThumbnail(r io.Reader) (b []byte, mimeType string, err error) { img, imgType, err := image.Decode(r) if err != nil { return } thumb := resize.Thumbnail(256, 192, img, resize.Lanczos3) buf := util.BufferPool.GetBuffer() defer util.BufferPool.Put(buf) switch imgType { case "gif": if err = gif.Encode(buf, thumb, nil); err != nil { return } mimeType = "image/gif" default: if err = jpeg.Encode(buf, thumb, &jpeg.Options{Quality: 80}); err != nil { return } mimeType = "image/jpeg" } b = buf.Bytes() return }
func Resize(oriImgPath, destImgPath, format string, width, height uint, force bool) (string, error) { oriImgFullPath, err := filepath.Abs(oriImgPath) if err != nil { return "", err } destImgFullPath, err := filepath.Abs(destImgPath) if err != nil { return "", err } imgFile, err := os.Open(oriImgFullPath) if err != nil { return "", err } var img image.Image if format == "jpeg" || format == "jpg" { img, err = jpeg.Decode(imgFile) } else if format == "png" { img, err = png.Decode(imgFile) } else { return "", errors.New("unknown format") } imgFile.Close() if err != nil { return "", err } if force { img = resize.Resize(width, height, img, resize.Lanczos3) } else { img = resize.Thumbnail(width, height, img, resize.Lanczos3) } out, err := os.Create(destImgFullPath) defer out.Close() if err != nil { return "", err } if format == "jpeg" || format == "jpg" { jpeg.Encode(out, img, nil) } else { // png png.Encode(out, img) } return destImgFullPath, nil }
// Fills the content of an internal (storage) User from the external representation. // All security and authorization checks must have been done before calling this // method. func (au *ApiUser) fillStorageUser(u *model.User) (err error) { if au.Email != nil { u.Email = *au.Email } if au.Password != nil { err = u.SetPassword(*au.Password) if err != nil { return err } } if au.Name != nil { u.Name = *au.Name } if au.Description != nil { u.Description = *au.Description } if au.Disability != nil { u.Disability = *au.Disability } if au.DisabilityType != nil { u.DisabilityType = *au.DisabilityType } if au.Phone != nil { u.Phone = *au.Phone } if au.EmergencyPhone != nil { u.EmergencyPhone = *au.EmergencyPhone } if au.Image != nil && len(*au.Image) != 0 { reader := bytes.NewReader(*au.Image) image, err := jpeg.Decode(reader) if err != nil { return err } if image.Bounds().Dx() > 128 || image.Bounds().Dy() > 128 { resizedImage := resize.Thumbnail(128, 128, image, resize.Bicubic) out := new(bytes.Buffer) jpeg.Encode(out, resizedImage, nil) u.Image = out.Bytes() } else { u.Image = *au.Image } } if au.PushToken != nil { u.PushToken = *au.PushToken } if au.AgentId != nil { u.AgentId = *au.AgentId } if au.IsAgent != nil { u.IsAgent = *au.IsAgent } return err }
func FilterResizeImage(image image.Image) (image.Image, error) { width := image.Bounds().Max.X - image.Bounds().Min.X height := image.Bounds().Max.Y - image.Bounds().Min.Y if (width < 300 && height < 300) || height > width*13/10 { return image, errors.New("Bad image format") } if width > 1000 { image = resize.Thumbnail(600, 600, image, resize.NearestNeighbor) } return image, nil }
func calcDir() (lookup []imageLookup) { var lookupTable []imageLookup dirOpen, dirOpenErr := os.Open(sourceDir) if dirOpenErr != nil { log.Println("Directory (Open): ", dirOpenErr) } defer dirOpen.Close() dirFiles, dirFilesErr := dirOpen.Readdir(-1) if dirFilesErr != nil { log.Println("Directory (Read Files): ", dirFilesErr) } for _, file := range dirFiles { if !file.Mode().IsRegular() { // ensures no mode bits are set fmt.Printf("Unable to access %s as mode bits are set (this usually means it's a directory)...", file.Name()) continue } if filepath.Ext(file.Name()) != ".JPG" && filepath.Ext(file.Name()) != ".jpg" { fmt.Printf("Unable to process %s as it does not have a JPG extension ...", file.Name()) continue } imgFile, openErr := os.Open(sourceDir + "/" + file.Name()) if openErr != nil { log.Println("Source File (Open): ", openErr) } imgData, imgFormat, decodeErr := image.Decode(imgFile) if decodeErr != nil { log.Println("Source File (Decode): ", decodeErr) continue } imgFile.Close() // closes the image file, to avoid "too many open files" error if !(imgFormat == "jpeg") { // checks if decoded format is JPEG fmt.Printf("Unable to decode %s as it is not JPEG\n", file.Name()) continue } tileSizeU := uint(tileSize) imgSmall := resize.Thumbnail(tileSizeU, tileSizeU, imgData, resize.NearestNeighbor) imgColor := averageColor(imgSmall) fileID := imageLookup{file.Name(), imgColor} lookupTable = append(lookupTable, fileID) fmt.Printf("Processing %s ... ", file.Name()) } return lookupTable }
func (r *Resize) createThumbnail(writer *bytes.Buffer, img *image.Image, ext string) { m := resize.Thumbnail(r.width, r.height, *img, r.interpolation) switch { case ext == "jpg": jpeg.Encode(writer, m, nil) case ext == "png": png.Encode(writer, m) case ext == "gif": gif.Encode(writer, m, nil) } }
func MakeThumbnail(data []byte) ([]byte, error) { img, _, err := image.Decode(bytes.NewReader(data)) if err != nil { return []byte{}, err } thumb := resize.Thumbnail(maxWidth, maxHeight, img, resize.Lanczos3) buf := new(bytes.Buffer) err = jpeg.Encode(buf, thumb, nil) if err != nil { return []byte{}, err } return buf.Bytes(), nil }
// 简单的缩放,指定最大宽和高 func ThumbnailSimple(maxWidth, maxHeight uint, img image.Image) image.Image { oriBounds := img.Bounds() oriWidth := uint(oriBounds.Dx()) oriHeight := uint(oriBounds.Dy()) if maxWidth == 0 { maxWidth = oriWidth } if maxHeight == 0 { maxHeight = oriHeight } return resize.Thumbnail(maxWidth, maxHeight, img, resize.Lanczos3) }
func cmd_thumbnail(file string, width uint, height uint, to string) { // 打开图片并解码 file_origin, _ := os.Open(file) origin, _ := jpeg.Decode(file_origin) defer file_origin.Close() canvas := resize.Thumbnail(width, height, origin, resize.Lanczos3) file_out, err := os.Create(to) if err != nil { log.Fatal(err) } defer file_out.Close() jpeg.Encode(file_out, canvas, &jpeg.Options{80}) }
func createSizedCopy(maxSize uint, filetype string, r io.Reader, w *storage.Writer) error { img, err := decodeImage(r, filetype) if err != nil { return errors.New("Failed to decode image: " + err.Error()) } tn := resize.Thumbnail(maxSize, maxSize, img, resize.Bicubic) err = encodeImage(w, filetype, tn) if err != nil { return errors.New("Failed to encode image: " + err.Error()) } return nil }
// Open the given path (assumed to contain an image) and then resize to 48px x 48px and // return in .ico format. func (ffs faviconFileSystem) Open(ctx context.Context, path string) (http.File, error) { f, err := ffs.FileSystem.Open(ctx, path) if err != nil { return nil, err } defer f.Close() stat, err := f.Stat() if err != nil { return nil, err } filename := stat.Name() ext := filepath.Ext(filename) var img image.Image switch ext { case ".jpeg", ".jpg": img, err = jpeg.Decode(f) case ".png": img, err = png.Decode(f) default: err = fmt.Errorf("unsupported favicon image source: %v", stat.Name()) } if err != nil { return nil, err } img = resize.Thumbnail(48, 48, img, resize.NearestNeighbor) buf := &bytes.Buffer{} err = ico.Encode(buf, img) if err != nil { return nil, err } icoFilename := strings.TrimSuffix(filename, ext) + ".ico" return &file{ ReadSeeker: bytes.NewReader(buf.Bytes()), stat: &fileInfo{ name: icoFilename, size: int64(buf.Len()), modTime: stat.ModTime(), }, }, nil }
func replaceTile(closestTile tileReplacement) (replaceSmall image.Image) { rpcFile, openErr := os.Open(sourceDir + "/" + closestTile.sourceName) if openErr != nil { log.Println("Source File (Open): ", openErr) } defer rpcFile.Close() rpcData, _, decodeErr := image.Decode(rpcFile) if decodeErr != nil { log.Println("Source File (Decode Tile): ", decodeErr) } tileSizeU := uint(tileSize) var smallTileSize = tileSizeU * 2 rpcSmall := resize.Thumbnail(smallTileSize, smallTileSize, rpcData, resize.NearestNeighbor) return rpcSmall }
func (m *maskDrawer) ComposeSized(overlay string, outFile string, size uint) { // Make sure the parent directory exists. createPath(outFile) log.Printf("composing %v\n", outFile) // Get the resized base image. img := m.getScaled(size) // Load the overlay image. overlayImg, err := loadImage(overlay) if err != nil { log.Printf("Failed to compose %v: %v\n", outFile, err) return } // Reduce the size of the overlay according to the scale. scaledSize := uint(float64(size) * m.scale) overlayImg = resize.Thumbnail(scaledSize, scaledSize, overlayImg, m.interp) // Compose the images. result := image.NewRGBA(img.Bounds()) draw.Draw(result, img.Bounds(), img, image.ZP, draw.Src) // The overlay image should be drawn with an offset as it may be scaled down. offset := (img.Bounds().Dx() - overlayImg.Bounds().Dx()) / 2 destPoint := image.Pt(offset, offset) r := image.Rectangle{destPoint, destPoint.Add(overlayImg.Bounds().Size())} draw.Draw(result, r, overlayImg, overlayImg.Bounds().Min, draw.Over) // Write out the result. fd, err := os.Create(outFile) if err != nil { log.Print(err) return } defer fd.Close() // TODO: Check using a buffered reader helps performance here. writer := bufio.NewWriter(fd) png.Encode(writer, result) writer.Flush() }
func (t *thumbnail) thumbnail(f goldsmith.File, thumbPath string) (goldsmith.File, error) { origImg, _, err := image.Decode(f) if err != nil { return nil, err } var thumbBuff bytes.Buffer thumbImg := resize.Thumbnail(t.dims, t.dims, origImg, resize.Bicubic) switch filepath.Ext(thumbPath) { case ".jpg", ".jpeg": err = jpeg.Encode(&thumbBuff, thumbImg, nil) case ".gif": err = gif.Encode(&thumbBuff, thumbImg, nil) case ".png": err = png.Encode(&thumbBuff, thumbImg) } return goldsmith.NewFileFromData(thumbPath, thumbBuff.Bytes()), nil }
func ThumbnailWithNFNT(dst, src string, width, height uint) error { r, err := os.Open(src) if err != nil { return err } defer r.Close() img, err := jpeg.Decode(r) if err != nil { return err } t := resize.Thumbnail(width, height, img, resize.NearestNeighbor) w, err := os.Create(dst) if err != nil { return err } defer w.Close() return jpeg.Encode(w, t, nil) }
// convert a src ppm image to a dst png image, resizing to a largest dimension // max if max != 0 func ppmToPng(src []byte, max int) ([]byte, error) { in := bytes.NewReader(src) img, _, err := image.Decode(in) if err != nil { return nil, err } // resize the image if necessary if max != 0 { img = resize.Thumbnail(uint(max), uint(max), img, resize.NearestNeighbor) } out := new(bytes.Buffer) err = png.Encode(out, img) if err != nil { return nil, err } return out.Bytes(), nil }
func ImageResize(filePath, newFilePath string, width, height uint, interp resize.InterpolationFunction, ext string) error { imgb, err := os.Open(filePath) if err != nil { return err } defer imgb.Close() img, _, err := image.Decode(imgb) if err != nil { return err } m := resize.Thumbnail(width, height, img, interp) out, err := os.Create(newFilePath) if err != nil { return err } defer out.Close() // write new image to file switch ext { case "jpg": jpeg.Encode(out, m, nil) break case "png": png.Encode(out, m) break default: break } return nil }
func main() { flag.Parse() maxSize = 500 if *maxSizeFlag != "" { temp, err := strconv.ParseUint(*maxSizeFlag, 10, 32) maxSize = uint(temp) if err != nil { panic(err) } } os.Mkdir("in", 0775) os.Mkdir("out", 0775) os.Mkdir("done", 0775) fmt.Println("Batch Image Resizer started\n") for { files, err := ioutil.ReadDir("in") if err != nil { panic(err) } if len(files) == 0 { time.Sleep(1 * time.Second) continue } currentFile = files[0].Name() temp := strings.Split(currentFile, ".") fileExt := strings.ToLower(temp[len(temp)-1]) file, err := os.Open("in/" + currentFile) if err != nil { fmt.Println(err) done() continue } if fileExt == "jpg" || fileExt == "jpeg" { img, err = jpeg.Decode(file) } else if fileExt == "png" { img, err = png.Decode(file) } else if fileExt == "gif" { img, err = gif.Decode(file) } else { fmt.Println("File " + currentFile + " has an unsupported file exension, must be <jpg|jpeg|png|gif>") done() continue } file.Close() var m image.Image m = resize.Thumbnail(maxSize, maxSize, img, resize.NearestNeighbor) out, err := os.Create("out/" + currentFile) if err != nil { fmt.Println(err) done() continue } if fileExt == "jpg" || fileExt == "jpeg" { err = jpeg.Encode(out, m, nil) } else if fileExt == "png" { err = png.Encode(out, m) } else if fileExt == "gif" { gif.Encode(out, m, nil) } else { fmt.Println("File :" + currentFile + "has an unsupported file exension, must be <jpg|jpeg|png|gif>") done() continue } if err != nil { fmt.Println(err) done() continue } out.Close() done() fmt.Println("Resized: ", currentFile) } }
// 根据需求实时获取缩略图片 // way string 缩略图生成方式: // 'auto': 原图全显优先,获取width或height最大,原图不会被截断 // 'full': 图片填充优先,将widthd和height,按照比例全部填充, 原图将会被截断 // func Thumb(way string, width uint, height uint, picturePath string) (*os.File, error) { /* 获取配置文件中上传根路径 */ revel.Config.SetSection(revel.RunMode) uploadRoot, _ := revel.Config.String("uploadpath") ext := filepath.Ext(picturePath) /* 检测是否是获取一个远端url图片的缩率图 */ picUrl, err := url.ParseRequestURI(picturePath) isRemotePic := false //if err == nil && picUrl.Scheme == "http" && (picUrl.Host == "img.show.wepiao.com" || picUrl.Host == "img.wxmovie.com" || picUrl.Host == "static.show.wepiao.com" || picUrl.Host == "static.task.18.tl:86") { if err == nil && picUrl.Scheme == "http" { isRemotePic = true uploadRoot += "/upload" savePath, saveName := HelperForFilePathCreator(uploadRoot, picturePath, false) picturePath = savePath + "/" + saveName + ext } if way != "full" { way = "auto" } fname := uploadRoot + "/" + picturePath thumbFile := fmt.Sprintf("%s_%s_%v_%v%v", fname, way, width, height, ext) /* 检查有没有现成的缩略图 */ _, err = os.Stat(thumbFile) if err == nil { // 如果有,直接读出 thumb, _ := os.Open(thumbFile) return thumb, nil } // fmt.Printf("没有现成缩率图\n") /* 没有现成的缩略图,需要实施生成, 查找原图片文件是否存在 */ finfo, err := os.Stat(fname) if err != nil { // 如果是获取远端图片,那就先获取. if isRemotePic { // fmt.Printf("是远端图片\n") client := http.Client{} reqImg, err := client.Get(picUrl.Scheme + "://" + picUrl.Host + picUrl.Path) defer reqImg.Body.Close() if err != nil { return nil, err } //如果是4开头的错误状态 则生成默认图片 if '4' == reqImg.Status[0] { fname = "/opt/www/static/pc/img/logo.png" way = "auto" } else { out, err := os.Create(fname) if err != nil { return nil, err } defer out.Close() io.Copy(out, reqImg.Body) } finfo, err = os.Stat(fname) // fmt.Printf("存储远端图片到: %#v\n", fname) } else if os.IsNotExist(err) || err.(*os.PathError).Err == syscall.ENOTDIR { return nil, errors.New("20108") } else { return nil, err } } if finfo.Mode().IsDir() { return nil, errors.New("10016") } file, err := os.Open(fname) if err != nil { if os.IsNotExist(err) { return nil, errors.New("20108") } return nil, err } defer file.Close() /* 生成缩略图 */ var img image.Image img, _, err = image.Decode(file) if err != nil { return nil, err } // 产生缩略图,等比例缩放 out, errF := os.Create(thumbFile) if errF != nil { return nil, errors.New("20108") } defer out.Close() var m image.Image // fmt.Printf("生成缩率图\n") origBounds := img.Bounds() origWidth := uint(origBounds.Dx()) origHeight := uint(origBounds.Dy()) if way == "full" { dst := image.NewRGBA(image.Rect(0, 0, int(width), int(height))) graphics.Thumbnail(dst, img) m = dst } else if width >= origWidth && height >= origHeight { bg := imaging.New(int(width), int(height), color.NRGBA{255, 255, 255, 255}) m = imaging.PasteCenter(bg, img) } else { m = resize.Thumbnail(width, height, img, resize.Lanczos3) } /* 生成文件 */ err = jpeg.Encode(out, m, &jpeg.Options{90}) if err != nil { err = png.Encode(out, m) } if err != nil { err = gif.Encode(out, m, nil) } if err != nil { return nil, err } /* 这里不知道如何将 image.Image类型转换为 io.Writer类型, 所以只有暂时在保存后,又重新读了次文件 */ thumb, _ := os.Open(thumbFile) return thumb, nil }
func pageFilesRegularThumbnail(w http.ResponseWriter, r *http.Request, p httprouter.Params) *httphelper.HandlerError { l := httphelper.NewHandlerLogEntry(r) values, err := url.ParseQuery(r.URL.RawQuery) if err != nil { return httphelper.NewHandlerErrorDef(errgo.Notef(err, "can not parse values from query")) } var width uint if values.Get("width") != "" { out, err := strconv.ParseUint(values.Get("width"), 10, 64) if err != nil { return httphelper.NewHandlerErrorDef(errgo.Notef(err, "can not parse width from parameters")) } width = uint(out) } var height uint if values.Get("height") != "" { out, err := strconv.ParseUint(values.Get("height"), 10, 64) if err != nil { return httphelper.NewHandlerErrorDef(errgo.Notef(err, "can not parse height from parameters")) } height = uint(out) } cachefile := filepath.Join(FlagFolderCache, p.ByName("path"), values.Get("width"), values.Get("height")+".jpg") if _, err := os.Stat(cachefile); os.IsNotExist(err) { l.Debug("Cachefile does not exist: ", cachefile) } else { l.Debug("Cachefile exists: ", cachefile) cache, err := os.Open(cachefile) if err != nil { l.Warning(errgo.Notef(err, "can not open cachefile from disk")) } else { _, err := io.Copy(w, cache) if err != nil { l.Warning(errgo.Notef(err, "can not copy cache file to response writer")) } else { l.Debug("Served from cachefile") w.Header().Set("Content-Type", "image/jpeg") return nil } } } pathfile := path.Join(FlagFolderGallery, p.ByName("path")) file, err := os.Open(pathfile) if err != nil { return httphelper.NewHandlerErrorDef(errgo.Notef(err, "can not open file from disk")) } defer file.Close() ext := filepath.Ext(pathfile) l.Debug("Filepath Extention: ", ext) var img image.Image switch ext { case ".jpeg", ".JPEG", ".jpg", ".JPG": img, err = jpeg.Decode(file) if err != nil { return httphelper.NewHandlerErrorDef(errgo.New("can not decode file as jpeg")) } case ".png", ".PNG": img, err = png.Decode(file) if err != nil { return httphelper.NewHandlerErrorDef(errgo.New("can not decode file as jpeg")) } default: return httphelper.NewHandlerErrorDef(errgo.New("dont know how to decode image with extention " + ext)) } l.Debug("Width: ", width) l.Debug("Height: ", height) err = os.MkdirAll(filepath.Dir(cachefile), 0755) if err != nil { return httphelper.NewHandlerErrorDef(errgo.Notef(err, "can not create cache folder")) } cache, err := os.Create(cachefile) if err != nil { return httphelper.NewHandlerErrorDef(errgo.Notef(err, "can not open cachefile from disk")) } defer cache.Close() writer := io.MultiWriter(w, cache) thumbnail := resize.Thumbnail(width, height, img, resize.MitchellNetravali) err = jpeg.Encode(writer, thumbnail, nil) if err != nil { return httphelper.NewHandlerErrorDef(errgo.Notef(err, "can not encode image to jpeg")) } w.Header().Set("Content-Type", "image/jpeg") return nil }
func (ski *SkinImg) scanImage() bool { img := resize.Thumbnail(800, 800, *ski.Img, resize.NearestNeighbor) bounds := img.Bounds() width := bounds.Size().X height := bounds.Size().Y totalPixels := width * height regionMap := make([]uint16, totalPixels) linked := make([]uint16, 1) var currentLabel uint16 = 1 //Label components for y := bounds.Min.Y; y < bounds.Max.Y; y++ { for x := bounds.Min.X; x < bounds.Max.X; x++ { r, g, b, _ := img.At(x, y).RGBA() index := (y-bounds.Min.Y)*width + (x - bounds.Min.X) var checkIndex [4]int //init checkedIndex for i := range checkIndex { nx := (i%3 - 1) + x ny := y + i/3 - 1 if nx < bounds.Min.X || ny < bounds.Min.Y || nx >= bounds.Max.X || ny >= bounds.Max.Y { checkIndex[i] = -1 } else { checkIndex[i] = (ny-bounds.Min.Y)*width + (nx - bounds.Min.X) } } if classifySkin(r, g, b) { min := uint16(math.MaxInt16) l := make([]uint16, 0) for _, cindex := range checkIndex { if cindex != -1 { val := regionMap[cindex] if val != 0 { found := false for _, v := range l { if val == v { found = true break } } if !found { l = append(l, val) } if val < min { min = val } } } } if min != uint16(math.MaxInt16) { regionMap[index] = min for _, v := range l { linked[v] = linked[min] } } else { regionMap[index] = currentLabel linked = append(linked, currentLabel) currentLabel++ } } } } //Merge var skinRegions Regions for y := bounds.Min.Y; y < bounds.Max.Y; y++ { for x := bounds.Min.X; x < bounds.Max.X; x++ { index := (y-bounds.Min.Y)*width + (x - bounds.Min.X) if regionMap[index] != 0 { regionMap[index] = linked[regionMap[index]] //search region found := false for _, r := range skinRegions { if r.Id == regionMap[index] { r.Count++ found = true break } } if !found { skinRegions = append(skinRegions, &Region{regionMap[index], 1}) } } } } //log.Println("component merged") //reduce noise for _, region := range skinRegions { if region.Count > 9 { //at least 3x3 ski.SkinRegions = append(ski.SkinRegions, region) } } return ski.analyseRegions() }