func analyzeFile(filename string, resize bool) (*Cover, error) { file, err := os.Open(filename) if err != nil { return nil, err } defer file.Close() img, _, err := image.Decode(file) if err != nil { return nil, err } if resize { start := time.Now() g := gift.New(gift.Resize(500, 0, gift.LanczosResampling)) dst := image.NewRGBA(g.Bounds(img.Bounds())) g.Draw(dst, img) img = dst fmt.Printf("- RESIZE %s took %s\n", path.Base(filename), time.Since(start)) } start := time.Now() bg, c1, c2, c3 := colorart.Analyze(img) fmt.Printf("- ANALYZE %s took %s\n", path.Base(filename), time.Since(start)) return &Cover{filename, bg.String(), c1.String(), c2.String(), c3.String()}, nil }
// Render draws rune r front the specified font at the specified dpi and scale. It returns a // grayscale image that is just large enough to contain the rune. func Render(font *truetype.Font, r rune, dpi, scale float64) (*image.Gray, error) { glyph := truetype.NewGlyphBuf() index := font.Index(r) glyph.Load(font, font.FUnitsPerEm(), index, truetype.FullHinting) ctx := freetype.NewContext() boxer := makeBoundingBoxer() ctx.SetSrc(image.NewUniform(color.White)) ctx.SetDst(boxer) ctx.SetClip(boxer.largeBounds) ctx.SetFontSize(250) ctx.SetDPI(dpi) ctx.SetFont(font) if err := glyph.Load(font, font.FUnitsPerEm(), font.Index(r), truetype.FullHinting); err != nil { return nil, fmt.Errorf("Unable to load glyph: %v\n", err) } var rp raster.Point rp.X = ctx.PointToFix32(0) rp.Y = ctx.PointToFix32(100) ctx.DrawString(string(r), rp) boxer.complete() g := gift.New( gift.Resize(int(float64(boxer.Bounds().Dx())*scale+0.5), int(float64(boxer.Bounds().Dy())*scale+0.5), gift.CubicResampling), ) dst := image.NewGray(g.Bounds(boxer.Bounds())) g.Draw(dst, boxer) return dst, nil }
// TODO Too min images should not resized func resizeImage(src image.Image, n int) image.Image { srcBounds := src.Bounds() gi := gift.New(gift.Resize(srcBounds.Max.Y/n, srcBounds.Max.Y/n, gift.LanczosResampling)) dst := image.NewRGBA(gi.Bounds(srcBounds)) gi.Draw(dst, src) return dst }
func newResizeFuncGift(resampling gift.Resampling) resizeFunc { return func(im image.Image) image.Image { g := gift.New(gift.Resize(width, height, resampling)) newIm := newImageFunc(g.Bounds(im.Bounds())) g.Draw(newIm, im) return newIm } }
// loadimage loads all the images of the deck into a map for later display func loadimage(d deck.Deck, m map[string]image.Image) { firstrun++ w, h := d.Canvas.Width, d.Canvas.Height cw := openvg.VGfloat(w) ch := openvg.VGfloat(h) msize := int(cw * .01) mx := cw / 2 my := ch * 0.05 mbg := "white" mfg := "black" for ns, s := range d.Slide { for ni, i := range s.Image { if !modfile(i.Name, StartTime) { continue } openvg.Start(w, h) if i.Link != "" { fmt.Fprintf(os.Stderr, "Found altimg %s\n", i.Link) } f, err := os.Open(i.Name) if err != nil { fmt.Fprintf(os.Stderr, "%v\n", err) continue } img, _, err := image.Decode(f) if err != nil { fmt.Fprintf(os.Stderr, "%v\n", err) continue } openvg.FillColor(mbg) openvg.Rect(0, 0, cw, ch) openvg.FillColor(mfg) openvg.TextMid(mx, my, fmt.Sprintf("Loading image %s %d from slide %d", i.Name, ni, ns), "sans", msize) bounds := img.Bounds() iw := i.Width ih := i.Height if i.Scale > 0 { iw = int(float64(iw) * (i.Scale / 100)) ih = int(float64(ih) * (i.Scale / 100)) } // if the specified dimensions are native use those, otherwise resize if iw == (bounds.Max.X-bounds.Min.X) && ih == (bounds.Max.Y-bounds.Min.Y) { m[i.Name] = img } else { g := gift.New(gift.Resize(iw, ih, gift.BoxResampling)) resized := image.NewRGBA(g.Bounds(img.Bounds())) g.Draw(resized, img) m[i.Name] = resized } f.Close() openvg.End() } } }
// nytheadlines retrieves data from the New York Times API, decodes and displays it. func (d *display) nytheadlines(section string, thumb bool) { hdim := dimen{x: 0, y: 0, width: d.width, height: d.height / 2} r, err := netread(fmt.Sprintf(NYTfmt, section, NYTAPIkey)) if err != nil { fmt.Fprintf(os.Stderr, "headline read error: %v\n", err) hdim.gerror(d.bgcolor, d.textcolor, "no headlines") return } defer r.Close() var data NYTHeadlines err = json.NewDecoder(r).Decode(&data) if err != nil { fmt.Fprintf(os.Stderr, "decode: %v\n", err) hdim.gerror(d.bgcolor, d.textcolor, "no headlines") return } x := d.width * 0.10 y := d.height * 0.10 thumbsize := int(d.height * 0.05) hdim.regionFill(d.bgcolor, d.textcolor) headsize := d.width / 80 spacing := openvg.VGfloat(thumbsize) for i := len(data.Results) - 1; i >= 0; i-- { openvg.Text(x, y, fromHTML.Replace(data.Results[i].Title), "serif", int(headsize)) if len(data.Results[i].Thumbnail) > 0 { img, imerr := netimage(data.Results[i].Thumbnail) if imerr != nil { continue } g := gift.New() g.Add(gift.Resize(0, thumbsize, gift.LanczosResampling)) gift.Resize(thumbsize, thumbsize, gift.BoxResampling) resized := image.NewRGBA(g.Bounds(img.Bounds())) g.Draw(resized, img) openvg.Img(x-100, y-(spacing*0.25), resized) } y = y + spacing } openvg.Image(d.width*0.05, 15, 30, 30, "poweredby_nytimes_30a.png") openvg.End() }
func (this *AvatarController) Post() { w := this.ResponseWriter r := this.Request data := e.Data{Status: 1, Msg: "上传成功"} log.Println("头像上传post") r.ParseMultipartForm(32 << 20) log.Println("表单解析") file, handler, err := r.FormFile("realPicFile") if err != nil { log.Println("上传错误") return } fileext := filepath.Ext(handler.Filename) log.Println("文件后缀名字" + fileext) if u.Check(fileext) == false { data.Status = 0 data.Msg = "不允许的上传类型" u.OutputJson(w, &data) return } cookie := u.Cookie{HTTP: this.HTTP} filename := cookie.GetCookie().UserId.Value + ".png" log.Println("文件名称" + filename) imgfile, _ := os.OpenFile(Upload_Dir+filename, os.O_CREATE|os.O_WRONLY, 0660) defer imgfile.Close() //把图片变成400X400尺寸的 m1, err := jpeg.Decode(file) if err != nil { panic(err) } bounds := m1.Bounds() //如果第二参数为0则保持横纵比 g := gift.New( gift.Resize(400, 400, gift.LanczosResampling), ) dst := image.NewRGBA(g.Bounds(bounds)) g.Draw(dst, m1) err = png.Encode(imgfile, dst) if err != nil { log.Println("上传失败") return } filedir := Show_Dir + filename data.Data = filedir log.Println(data) u.OutputJson(w, &data) }
func resizeImage(img image.Image, size image.Point) image.Image { g := gift.New(gift.Resize(size.X, size.Y, gift.LanczosResampling)) rect := image.Rectangle{Max: size} switch img.(type) { case *image.Gray: dst := image.NewGray(rect) g.Draw(dst, img) return dst default: dst := image.NewRGBA(rect) g.Draw(dst, img) return dst } }
func (prc *ResizeProcessor) getFilter(width, height int, params imageserver.Params) (gift.Filter, error) { rsp, err := prc.getResampling(params) if err != nil { return nil, err } if !params.Has("mode") || width == 0 || height == 0 { return gift.Resize(width, height, rsp), nil } mode, err := params.GetString("mode") if err != nil { return nil, err } switch mode { case "fit": return gift.ResizeToFit(width, height, rsp), nil case "fill": return gift.ResizeToFill(width, height, rsp, gift.CenterAnchor), nil } return nil, &imageserver.ParamError{Param: "mode", Message: "invalid value"} }
func (this *AvatarController) Cut() { r := this.Request data := e.Data{Status: 1, Msg: "上传成功"} r.ParseForm() x, err := strconv.Atoi(r.FormValue("x")) y, err := strconv.Atoi(r.FormValue("y")) x2, err := strconv.Atoi(r.FormValue("x2")) y2, err := strconv.Atoi(r.FormValue("y2")) fileName := r.FormValue("fileName") log.Println(x, y, x2, y2, fileName) g := gift.New( gift.Crop(image.Rect(x, y, x2, y2)), gift.Resize(220, 220, gift.LanczosResampling), ) log.Println("图片名称" + fileName) //打开待处理的图片 file, err := os.Open(fileName) if err != nil { panic(err) } defer file.Close() m1, err := png.Decode(file) if err != nil { panic(err) } bounds := m1.Bounds() dst := image.NewRGBA(g.Bounds(bounds)) g.Draw(dst, m1) cookie := u.Cookie{HTTP: this.HTTP} filename := cookie.GetCookie().UserId.Value + ".png" imgfile, err := os.Create(Avatar_ReDir + filename) os.Remove(Upload_Dir + filename) defer imgfile.Close() err = png.Encode(imgfile, dst) u.OutputJson(this.ResponseWriter, &data) }
func doit(fn string) (string, error) { file, err := os.Open(fn) if err != nil { return "", err } defer file.Close() img, _, err := image.Decode(file) if err != nil { return "", err } b := img.Bounds() var g *gift.GIFT if b.Max.X-b.Min.X >= resizeThreshold || b.Max.Y-b.Min.Y >= resizeThreshold { g = gift.New( gift.Resize(resizeSize, resizeSize, gift.LanczosResampling), gift.GaussianBlur(sigma)) } else { g = gift.New(gift.GaussianBlur(sigma)) } dst := image.NewRGBA(g.Bounds(img.Bounds())) g.Draw(dst, img) img = dst fn = path.Base(fn) ext := path.Ext(fn) fn = fmt.Sprintf("./%s.blur%s", fn[:len(fn)-len(ext)], ext) w, _ := os.Create(fn) defer w.Close() if err = jpeg.Encode(w, dst, nil); err != nil { return "", err } return fn, nil }
func analyzeFile(filename string) (bg, c1, c2, c3 colorart.Color) { file, err := os.Open(filename) defer file.Close() if err != nil { log.Fatal(err) } img, _, err := image.Decode(file) if err != nil { log.Fatal(err) } b := img.Bounds() if b.Max.X-b.Min.X > resizeThreshold || b.Max.Y-b.Min.Y > resizeThreshold { g := gift.New(gift.Resize(resizeSize, 0, gift.LanczosResampling)) dst := image.NewRGBA(image.Rect(0, 0, resizeSize, resizeSize)) g.Draw(dst, img) img = dst } return colorart.Analyze(img) }
// GreyscaleDctMatrix Computes the Dct of a greyscale image using matrixes func GreyscaleDctMatrix(im image.Image) uint64 { greyFilter := gift.Grayscale() convFilter := gift.Convolution([]float32{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }, true, false, false, 0) resizeFilter := gift.Resize(32, 32, gift.LinearResampling) g := gift.New(greyFilter, convFilter, resizeFilter) dst := image.NewRGBA(g.Bounds(im.Bounds())) g.Draw(dst, im) /* out, _ := os.Create("/Users/danielriley/desktop/output.jpg") var opt jpeg.Options opt.Quality = 80 _ = jpeg.Encode(out, dst, &opt) // put quality to 80% out1, _ := os.Create("/Users/danielriley/desktop/output1.jpg") opt.Quality = 80 _ = jpeg.Encode(out1, im, &opt) // put quality to 80% return 0 */ //width := im.Bounds().Max.X //height := im.Bounds().Max.Y m := make([][]float64, 32) for i := 0; i < 32; i++ { m[i] = make([]float64, 32) for j := 0; j < 32; j++ { _, _, b, _ := dst.At(i, j).RGBA() m[i][j] = float64(b) } } /* out, _ := os.Create("/Users/danielriley/desktop/output.jpg") var opt jpeg.Options opt.Quality = 80 _ = jpeg.Encode(out, dst, &opt) // put quality to 80% out1, _ := os.Create("/Users/danielriley/desktop/output1.jpg") opt.Quality = 80 _ = jpeg.Encode(out1, im, &opt) // put quality to 80% */ imMatrix := FloatMatrix(m) dctMatrix := NewDCTMatrix(32) // We can safely ignore errors here, since the sizes // always match. dct, _ := dctMatrix.Multiply(imMatrix) dct, _ = dct.Multiply(dctMatrix.Transposed()) sub, _ := dct.SubMatrix(1, 1, 8, 8) values := sub.UnrollX() // We need the original values, so we must sort a copy cpy := make([]float64, len(values)) copy(cpy, values) sort.Float64s(cpy) median := (cpy[64/2-1] + cpy[64/2]) / 2 fmt.Println("got median ", median) bit := uint64(1) hash := uint64(0) for _, v := range values { if v > median { hash |= bit } bit <<= 1 } fmt.Println("calculated hash ", hash) return hash /* imgMtx, err := manipulator.GrayImageToMatrix(img) if err != nil { panic(err) } dctMtx, err := createDctMatrix(img.Bounds().Max.X, img.Bounds().Max.Y) if err != nil { panic(err) } dctMtxTransp := dctMtx.T() // Transpose dctMtx.Mul(dctMtx, imgMtx) dctMtx.Mul(dctMtx, dctMtxTransp) dctImage, err := manipulator.CropMatrix(dctMtx, 0, 0, 7, 7) if err != nil { panic(err) } subsec := dctImage.RawMatrix().Data median := median(subsec) var one, hash uint64 = 1, 0 for i := 0; i < len(subsec); i++ { current := subsec[i] if current > median { hash |= one } one = one << 1 } return hash */ }
func (processor *Processor) Execute(src *Image, dst io.Writer, query *Query) { processor.gift.Empty() quality := 100 if query.Count() > 0 { // resize if query.Has("w") || query.Has("h") { width := query.GetInt("w") height := query.GetInt("h") if width > 0 || height > 0 { processor.gift.Add(gift.Resize(width, height, gift.LanczosResampling)) } } // crop if query.Has("c") { c := query.GetIntArray("c") if len(c) == 4 { processor.gift.Add(gift.Crop(image.Rect(c[0], c[1], c[2], c[3]))) } } // grayscale if query.Has("grayscale") { processor.gift.Add(gift.Grayscale()) } // sepia if query.Has("sepia") { sepia := query.GetInt("sepia") if sepia <= 100 { processor.gift.Add(gift.Sepia(float32(sepia))) } } // contrast if query.Has("contrast") { contrast := query.GetInt("contrast") processor.gift.Add(gift.Contrast(float32(contrast))) } // brightness if query.Has("brightness") { brightness := query.GetInt("brightness") processor.gift.Add(gift.Brightness(float32(brightness))) } // saturation if query.Has("saturation") { saturation := query.GetInt("saturation") processor.gift.Add(gift.Saturation(float32(saturation))) } // colorize if query.Has("colorize") { colorize := query.GetIntArray("colorize") if len(colorize) == 3 { processor.gift.Add(gift.Colorize(float32(colorize[0]), float32(colorize[1]), float32(colorize[2]))) } } // colorbalance if query.Has("colorbalance") { colorbalance := query.GetIntArray("colorbalance") if len(colorbalance) == 3 { processor.gift.Add(gift.ColorBalance(float32(colorbalance[0]), float32(colorbalance[1]), float32(colorbalance[2]))) } } // quality if query.Has("q") { q := query.GetInt("q") if q > 0 && q < 100 { quality = q } } // Draw if len(processor.gift.Filters) > 0 { rgba := image.NewRGBA(processor.gift.Bounds(src.Object.Bounds())) processor.gift.Draw(rgba, src.Object) jpeg.Encode(dst, rgba, &jpeg.Options{Quality: quality}) return } } // default jpeg.Encode(dst, src.Object, &jpeg.Options{Quality: quality}) }
func (i ImageFile) Render(w io.Writer, x, y int, align string) error { // Open file file, err := os.Open(i.Path) if err != nil { return err } defer file.Close() img, format, err := image.Decode(file) if err != nil { return err } size := img.Bounds().Size() // Default to current size if x and y are 0 if x == 0 && y == 0 { x = size.X y = size.Y } // Calculate same aspect ratio y if y == 0 { g := gift.New(gift.Resize(x, 0, gift.LanczosResampling)) y = g.Bounds(img.Bounds()).Size().Y } // Calculate same aspect ratio x if x == 0 { g := gift.New(gift.Resize(0, y, gift.LanczosResampling)) x = g.Bounds(img.Bounds()).Size().X } // Resize image keeping aspect ration, filling space we have g := gift.New() if size.X > size.Y { // image is wider than it's high, resize width after g.Add(gift.Resize(0, y, gift.LanczosResampling)) g.Add(gift.Resize(x, 0, gift.LanczosResampling)) } else { g.Add(gift.Resize(x, 0, gift.LanczosResampling)) g.Add(gift.Resize(0, y, gift.LanczosResampling)) } // Compute resized image keeping aspect ratio dst := image.NewRGBA(g.Bounds(img.Bounds())) g.Draw(dst, img) // Calculate starting point in destination image var spx, spy int if align[0] == 'c' { spy = (y - dst.Bounds().Size().Y) / 2 } else if align[0] == 'b' { spy = y - dst.Bounds().Size().Y } if align[1] == 'c' { spx = (x - dst.Bounds().Size().X) / 2 } else if align[1] == 'r' { spx = x - dst.Bounds().Size().X } startingPoint := image.Pt(spx, spy) // Compute resized image in right canvas finalDst := image.NewRGBA(image.Rect(0, 0, x, y)) sr := dst.Bounds() finalDstRect := sr.Add(startingPoint) draw.Draw(finalDst, finalDstRect, dst, sr.Min, draw.Src) if format == "jpg" || format == "jpeg" { err = jpeg.Encode(w, finalDst, &jpeg.Options{ Quality: 90, }) } else if format == "png" { err = png.Encode(w, finalDst) } else { return errors.New("Unrecognized format: " + format) } return err }
func ResizeFilter(width int, height int) *gift.GIFT { g := gift.New(gift.Resize(width, height, gift.LanczosResampling)) return g }