// decoder reads an image from r and modifies the image as defined by opts. // swapDimensions indicates the decoded image will be rotated after being // returned, and when interpreting opts, the post-rotation dimensions should // be considered. // The decoded image is returned in im. The registered name of the decoder // used is returned in format. If the image was not successfully decoded, err // will be non-nil. If the decoded image was made smaller, needRescale will // be true. func decode(r io.Reader, opts *DecodeOpts, swapDimensions bool) (im image.Image, format string, err error, needRescale bool) { if opts == nil { // Fall-back to normal decode. im, format, err = image.Decode(r) return im, format, err, false } var buf bytes.Buffer tr := io.TeeReader(r, &buf) ic, format, err := image.DecodeConfig(tr) if err != nil { return nil, "", err, false } mr := io.MultiReader(&buf, r) b := image.Rect(0, 0, ic.Width, ic.Height) sw, sh, needRescale := opts.rescaleDimensions(b, swapDimensions) if !needRescale { im, format, err = image.Decode(mr) return im, format, err, false } imageDebug(fmt.Sprintf("Resizing from %dx%d -> %dx%d", ic.Width, ic.Height, sw, sh)) if format == "cr2" { // Replace mr with an io.Reader to the JPEG thumbnail embedded in a // CR2 image. if mr, err = cr2.NewReader(mr); err != nil { return nil, "", err, false } format = "jpeg" } if format == "jpeg" && fastjpeg.Available() { factor := fastjpeg.Factor(ic.Width, ic.Height, sw, sh) if factor > 1 { var buf bytes.Buffer tr := io.TeeReader(mr, &buf) im, err = fastjpeg.DecodeDownsample(tr, factor) switch err.(type) { case fastjpeg.DjpegFailedError: log.Printf("Retrying with jpeg.Decode, because djpeg failed with: %v", err) im, err = jpeg.Decode(io.MultiReader(&buf, mr)) case nil: // fallthrough to rescale() below. default: return nil, format, err, false } return rescale(im, sw, sh), format, err, true } } // Fall-back to normal decode. im, format, err = image.Decode(mr) if err != nil { return nil, "", err, false } return rescale(im, sw, sh), format, err, needRescale }
func DescribeImage(uri string) (mediatype string, width, height int, filelength int64, err error) { c := curler{ dial_timeo: connection_speedup_timeout, } resp, err := c.do_get(uri, nil) if err != nil { return } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { filelength = int64(-resp.StatusCode) err = fmt.Errorf("%v: %v", resp.StatusCode, http.StatusText(resp.StatusCode)) return } filelength = resp.ContentLength // -1 means unknown if filelength < 16 && filelength >= 0 { err = fmt.Errorf("%v: %v", filelength, "content-length insufficient info") return } ct := resp.Header.Get("Content-Type") mediatype, _, _ = mime.ParseMediaType(ct) types := strings.Split(mediatype, "/") if types[0] != "image" { err = fmt.Errorf("%v: unknown mime %v", uri, mediatype) return } ic, mediatype, err := image.DecodeConfig(resp.Body) width = ic.Width height = ic.Height return }
func parseImg(raw []byte) (imgInfo, error) { //fmt.Printf("----------\n") var info imgInfo imgConfig, formatname, err := image.DecodeConfig(bytes.NewBuffer(raw)) if err != nil { return info, err } info.formatName = formatname if formatname == "jpeg" { err = parseImgJpg(&info, imgConfig) if err != nil { return info, err } info.data = raw } else if formatname == "png" { err = paesePng(raw, &info, imgConfig) if err != nil { return info, err } } //fmt.Printf("%#v\n", info) return info, nil }
func TestProc(t *testing.T) { cases := map[*Options]*expected{ &Options{ Format: "jpg", Quality: 80, Method: 3, Base: Construct(new(Source), "http://"+test_server+"/"+file_name).(*Source), Scale: Construct(new(Scale), "100x").(*Scale), }: &expected{Size: &PixelDim{100, 75}, ImgType: "jpeg"}, &Options{ Format: "jpg", Quality: 80, Base: Construct(new(Source), "http://"+test_server+"/"+file_name).(*Source), CropRoi: Construct(new(Roi), "1,1,500,500").(*Roi), Scale: nil, }: &expected{&PixelDim{500, 500}, "jpeg"}, &Options{ Format: "jpg", Quality: 80, Method: 3, Base: Construct(new(Source), "http://"+test_server+"/"+file_name).(*Source), Scale: Construct(new(Scale), "100x").(*Scale), CropRoi: Construct(new(Roi), "center,500,500").(*Roi), }: &expected{&PixelDim{100, 100}, "jpeg"}, &Options{ Format: "png", Method: 3, Base: Construct(new(Source), "http://"+test_server+"/"+file_name).(*Source), Scale: Construct(new(Scale), "100x").(*Scale), }: &expected{&PixelDim{100, 75}, "png"}, &Options{ Format: "png", Method: 3, Base: Construct(new(Source), "http://"+test_server+"/"+file_name).(*Source), }: &expected{&PixelDim{1024, 768}, "png"}, } for option, want := range cases { b := Do(option) if b == nil { t.Errorf("Expected data, result is nil\n") } cfg, imgType, err := image.DecodeConfig(bytes.NewReader(b)) if err != nil { t.Error(err) } resultSize := &PixelDim{cfg.Width, cfg.Height} if !reflect.DeepEqual(resultSize, want.Size) { t.Errorf("Expected size is %v, got %v\n", want.Size, resultSize) } if imgType != want.ImgType { t.Errorf("Expected image type is %v, got %v", want.ImgType, imgType) } } }
func (m *markedImage) Config() (image.Config, error) { cfg, _, err := image.DecodeConfig(bytes.NewReader(m.Img)) if err != nil { return image.Config{}, e.New(err) } return cfg, nil }
func (p *photo) Config() (image.Config, error) { cfg, _, err := image.DecodeConfig(bytes.NewReader(p.Buf)) if err != nil { return image.Config{}, e.New(err) } return cfg, nil }
func detectFormat(imgBytes []byte) (string, *serverError) { _, imgFormat, err := image.DecodeConfig(bytes.NewReader(imgBytes)) if err != nil { return "", &serverError{fmt.Sprintf("could not detect image format: %s", err), 501} } return imgFormat, nil }
func NewImage(path string) (*Image, error) { f, ferr := os.Open(path) if ferr != nil { fmt.Fprintf(os.Stderr, "%v\n", ferr) return nil, fmt.Errorf("Could not open image %v", ferr) } defer f.Close() imConf, _, err := image.DecodeConfig(f) if err != nil { return nil, fmt.Errorf("Could not decode image", err) } im := Image{} im.Path = path pathArr := strings.Split(path, "/") im.Url = "/inc/" + pathArr[len(pathArr)-1] fmt.Println(im.Url) size := geom.Rect{} size.Min = geom.Coord{X: 0, Y: 0} size.Max = geom.Coord{X: float64(imConf.Width), Y: float64(imConf.Height)} im.Size = size return &im, nil }
func getFileInfo(base *url.URL, reader io.Reader) (*result, error) { h := sha1.New() buf := make([]byte, 1024) tee := io.TeeReader(reader, h) res := result{} config, format, err := image.DecodeConfig(tee) if err != nil { return nil, err } res.Width = config.Width res.Height = config.Height for ; err != io.EOF; _, err = tee.Read(buf) { if err != nil { return nil, err } } hash := base64.RawURLEncoding.EncodeToString(h.Sum(nil)) hashURL, _ := url.Parse(hash + "." + format) res.URI = base.ResolveReference(hashURL).String() res.UUID = uuid.NewV5(uuid.NamespaceURL, res.URI) return &res, nil }
func (c *Single) HandleUpload(avatar []byte) revel.Result { // Validation rules. c.Validation.Required(avatar) c.Validation.MinSize(avatar, 2*KB). Message("Minimum a file size of 2KB expected") c.Validation.MaxSize(avatar, 2*MB). Message("File cannot be larger than 2MB") // Check format of the file. conf, format, err := image.DecodeConfig(bytes.NewReader(avatar)) c.Validation.Required(err == nil).Key("avatar"). Message("Incorrect file format") c.Validation.Required(format == "jpeg" || format == "png").Key("avatar"). Message("JPEG or PNG file format is expected") // Check resolution. c.Validation.Required(conf.Height >= 150 && conf.Width >= 150).Key("avatar"). Message("Minimum allowed resolution is 150x150px") // Handle errors. if c.Validation.HasErrors() { c.Validation.Keep() c.FlashParams() return c.Redirect(routes.Single.Upload()) } return c.RenderJson(FileInfo{ ContentType: c.Params.Files["avatar"][0].Header.Get("Content-Type"), Filename: c.Params.Files["avatar"][0].Filename, RealFormat: format, Resolution: fmt.Sprintf("%dx%d", conf.Width, conf.Height), Size: len(avatar), Status: "Successfully uploaded", }) }
// Get implements Server func (srv *DecodeCheckServer) Get(params imageserver.Params) (*imageserver.Image, error) { im, err := srv.Server.Get(params) if err != nil { return nil, err } if srv.PreDecode != nil { err = srv.PreDecode(im, params) if err != nil { return nil, err } } cfg, format, err := image.DecodeConfig(bytes.NewReader(im.Data)) if err != nil { return nil, &imageserver.ImageError{Message: err.Error()} } if format != im.Format { return nil, &imageserver.ImageError{Message: fmt.Sprintf("decoded format \"%s\" does not match image format \"%s\"", format, im.Format)} } if srv.PostDecode != nil { err = srv.PostDecode(cfg, format, params) if err != nil { return nil, err } } return im, err }
func sizer(originalTag string) string { tag := originalTag if strings.Index(tag, widthAttr) > -1 && strings.Index(tag, heightAttr) > -1 { return tag // width & height attributes are already present } match := srcRx.FindStringSubmatch(tag) if match == nil { fmt.Println("can't find <img>'s src attribute", tag) return tag } file, err := os.Open(match[1]) if err != nil { fmt.Println("can't open image to read its size:", err) return tag } defer file.Close() config, _, err := image.DecodeConfig(file) if err != nil { fmt.Println("can't ascertain the image's size:", err) return tag } tag, end := tagEnd(tag) if strings.Index(tag, widthAttr) == -1 { tag += fmt.Sprintf(` %s"%d"`, widthAttr, config.Width) } if strings.Index(tag, heightAttr) == -1 { tag += fmt.Sprintf(` %s"%d"`, heightAttr, config.Height) } tag += end return tag }
func (m *Manager) LoadFromPath(path string) *Data { setupTextureList() m.mutex.RLock() var data *Data var ok bool if data, ok = m.registry[path]; ok { m.mutex.RUnlock() m.mutex.Lock() data.accessed = generation m.mutex.Unlock() return data } m.mutex.RUnlock() m.mutex.Lock() if data, ok = m.deleted[path]; ok { delete(m.deleted, path) } else { data = &Data{} } data.accessed = generation m.registry[path] = data m.mutex.Unlock() f, err := os.Open(path) if err != nil { return data } config, _, err := image.DecodeConfig(f) f.Close() data.dx = config.Width data.dy = config.Height load_requests <- loadRequest{path, data} return data }
// Slower operations to fill props struct func (p *props) load(h hash.Hash, name string) *props { p.mime = mime.TypeByExtension(p.ext) r, err := os.Open(name) if err != nil { log.Print(name, ": Props: ", err) return p } defer r.Close() p.ftype = mapType(p.mime) // TODO: this is quite unreadable copy(p.chash[:], filehash(name, h, r)) copy(p.dident[:], strhash(p.dir, h)) // If the extension is empty, we need to detect // the MIME type via file contents if p.mime == "" { p.mime = sniffMIME(name, r) } // Non-images are completely processed at this point if !strings.HasPrefix(p.mime, "image/") { return p } // Image-specific processing if _, err := r.Seek(0, 0); err != nil { log.Print(name, ": Seek: ", err) return p } imgconf, _, err := image.DecodeConfig(r) if err != nil { log.Print(name, ": Image decoder: ", err) return p } p.isize = image.Point{imgconf.Width, imgconf.Height} return p }
// Parse parses an url and returns structurized representation func (p *Parser) Parse(u string) *oembed.Info { if p.client == nil { transport := &http.Transport{DisableKeepAlives: true, Dial: p.Dial} p.client = &http.Client{Timeout: p.WaitTimeout, Transport: transport, CheckRedirect: p.skipRedirectIfFoundOembed} } p.fetchURLCalls = 0 info := p.parseOembed(u) // and now we try to set missing image sizes if info != nil { width := info.ThumbnailWidth if len(info.ThumbnailURL) > 0 && width == 0 { p.fetchURLCalls = 0 data, newURL, _, err := p.fetchURL(info.ThumbnailURL) if err == nil { info.ThumbnailURL = newURL config, _, err := image.DecodeConfig(bytes.NewReader(data)) if err == nil { info.ThumbnailWidth = uint64(config.Width) info.ThumbnailHeight = uint64(config.Height) } } } } return info }
func getImageDimension(r io.Reader) (int, int, error) { image, _, err := image.DecodeConfig(r) if err != nil { return -1, -1, err } return image.Width, image.Height, nil }
func fetchIconDetails(url string) Icon { i := Icon{URL: url} response, e := get(url) if e != nil { i.Error = e return i } b, e := getBodyBytes(response) if e != nil { i.Error = e return i } cfg, format, e := image.DecodeConfig(bytes.NewReader(b)) if e != nil { i.Error = fmt.Errorf("besticon: unknown image format: %s", e) return i } i.Width = cfg.Width i.Height = cfg.Height i.Format = format i.Bytes = len(b) i.Sha1sum = sha1Sum(b) if keepImageBytes { i.ImageData = b } return i }
// DecodeDownsample decodes JPEG data in r, down-sampling it by factor. // If djpeg is not found, err is ErrDjpegNotFound and r is not read from. // If the execution of djpeg, or decoding the resulting PNM fails, error will // be of type DjpegFailedError. func DecodeDownsample(r io.Reader, factor int) (image.Image, error) { if !Available() { return nil, ErrDjpegNotFound } switch factor { case 1, 2, 4, 8: default: return nil, fmt.Errorf("fastjpeg: unsupported sample factor %d", factor) } buf := new(bytes.Buffer) tr := io.TeeReader(r, buf) ic, format, err := image.DecodeConfig(tr) if err != nil { return nil, err } if format != "jpeg" { return nil, fmt.Errorf("fastjpeg: Unsupported format %q", format) } var bpp int switch ic.ColorModel { case color.YCbCrModel: bpp = 4 // JPEG will decode to RGB, and we'll expand inplace to RGBA. case color.GrayModel: bpp = 1 default: return nil, fmt.Errorf("fastjpeg: Unsupported thumnbnail color model %T", ic.ColorModel) } args := []string{djpegBin, "-scale", fmt.Sprintf("1/%d", factor)} cmd := exec.Command(args[0], args[1:]...) cmd.Stdin = types.NewStatsReader(djpegBytesWrittenVar, io.MultiReader(buf, r)) // Allocate space for the RGBA / Gray pixel data plus some extra for PNM // header info. Explicitly allocate all the memory upfront to prevent // many smaller allocations. pixSize := ic.Width*ic.Height*bpp/factor/factor + 128 w := bytes.NewBuffer(make([]byte, 0, pixSize)) cmd.Stdout = w stderrW := new(bytes.Buffer) cmd.Stderr = stderrW if err := cmd.Run(); err != nil { // cmd.ProcessState == nil happens if /lib/*/ld-x.yz.so is missing, which gives you the ever useful: // "fork/exec /usr/bin/djpeg: no such file or directory" error message. // So of course it only happens on broken systems and this check is probably overkill. if cmd.ProcessState == nil || !cmd.ProcessState.Success() { djpegFailureVar.Add(1) return nil, DjpegFailedError{Err: fmt.Errorf("%v: %s", err, stderrW)} } // false alarm, so proceed. See http://camlistore.org/issue/550 } djpegSuccessVar.Add(1) djpegBytesReadVar.Add(int64(w.Len())) m, err := readPNM(w) if err != nil { return m, DjpegFailedError{Err: err} } return m, nil }
func DecodeConfig(filename string) (image.Config, string, error) { f, err := os.Open(filename) if err != nil { panic("Error open file") } defer f.Close() return image.DecodeConfig(bufio.NewReader(f)) }
func decodeConfig(filename string) (image.Config, string, error) { f, err := os.Open(filename) if err != nil { return image.Config{}, "", err } defer f.Close() return image.DecodeConfig(bufio.NewReader(f)) }
func loadTexture(fileName string) (uint32, error) { imgFile, err := os.Open("./res/textures/" + fileName) if err != nil { return 0, err } imgCfg, _, err := image.DecodeConfig(imgFile) if err != nil { return 0, err } _, err = imgFile.Seek(0, 0) if err != nil { return 0, err } w, h := int32(imgCfg.Width), int32(imgCfg.Height) img, _, err := image.Decode(imgFile) if err != nil { return 0, err } buffer := make([]byte, w*h*4) index := 0 for y := 0; y < int(h); y++ { for x := 0; x < int(w); x++ { pixel := img.At(x, y).(color.NRGBA) buffer[index] = pixel.R buffer[index+1] = pixel.G buffer[index+2] = pixel.B buffer[index+3] = pixel.A index += 4 } } var texture uint32 gl.GenTextures(1, &texture) gl.BindTexture(gl.TEXTURE_2D, texture) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT) gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST) gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST) gl.TexImage2D( gl.TEXTURE_2D, 0, gl.RGBA8, w, h, 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(buffer)) return texture, nil }
// blobref: of the file or schema blob // ss: the parsed file schema blob // bm: keys to populate func (ix *Index) populateFile(blobRef *blobref.BlobRef, ss *schema.Superset, bm BatchMutation) error { seekFetcher := blobref.SeekerFromStreamingFetcher(ix.BlobSource) fr, err := ss.NewFileReader(seekFetcher) if err != nil { // TODO(bradfitz): propagate up a transient failure // error type, so we can retry indexing files in the // future if blobs are only temporarily unavailable. // Basically the same as the TODO just below. log.Printf("index: error indexing file, creating NewFileReader %s: %v", blobRef, err) return nil } defer fr.Close() mime, reader := magic.MimeTypeFromReader(fr) sha1 := sha1.New() var copyDest io.Writer = sha1 var withCopyErr func(error) // or nil if strings.HasPrefix(mime, "image/") { pr, pw := io.Pipe() copyDest = io.MultiWriter(copyDest, pw) confc := make(chan *image.Config, 1) go func() { conf, _, err := image.DecodeConfig(pr) defer io.Copy(ioutil.Discard, pr) if err == nil { confc <- &conf } else { confc <- nil } }() withCopyErr = func(err error) { pw.CloseWithError(err) if conf := <-confc; conf != nil { bm.Set(keyImageSize.Key(blobRef), keyImageSize.Val(fmt.Sprint(conf.Width), fmt.Sprint(conf.Height))) } } } size, err := io.Copy(copyDest, reader) if f := withCopyErr; f != nil { f(err) } if err != nil { // TODO: job scheduling system to retry this spaced // out max n times. Right now our options are // ignoring this error (forever) or returning the // error and making the indexing try again (likely // forever failing). Both options suck. For now just // log and act like all's okay. log.Printf("index: error indexing file %s: %v", blobRef, err) return nil } wholeRef := blobref.FromHash("sha1", sha1) bm.Set(keyWholeToFileRef.Key(wholeRef, blobRef), "1") bm.Set(keyFileInfo.Key(blobRef), keyFileInfo.Val(size, ss.FileName, mime)) return nil }
func getImageInfo(file io.Reader) (int, int, string) { img, mime, err := image.DecodeConfig(file) if err != nil { return 0, 0, "application/unknown" } return img.Width, img.Height, "image/" + mime }
// imageConfigFromReader calls image.DecodeConfig on r. It returns an // io.Reader that is the concatentation of the bytes read and the remaining r, // the image configuration, and the error from image.DecodeConfig. func imageConfigFromReader(r io.Reader) (io.Reader, image.Config, error) { header := new(bytes.Buffer) tr := io.TeeReader(r, header) // We just need width & height for memory considerations, so we use the // standard library's DecodeConfig, skipping the EXIF parsing and // orientation correction for images.DecodeConfig. conf, _, err := image.DecodeConfig(tr) return io.MultiReader(header, r), conf, err }
func getImageWidthForFile(filename string) int { f, err := os.Open(filename) check(err) defer f.Close() icfg, _, err := image.DecodeConfig(f) check(err) return icfg.Width }
func loadImage(c appengine.Context, f *Feed) string { s := f.Link if s == "" { s = f.Url } u, err := url.Parse(s) if err != nil { return "" } u.Path = "/favicon.ico" u.RawQuery = "" u.Fragment = "" g := goon.FromContext(c) i := &Image{Id: u.String()} if err := g.Get(i); err == nil { return i.Url } client := urlfetch.Client(c) r, err := client.Get(u.String()) if err != nil || r.StatusCode != http.StatusOK || r.ContentLength == 0 { return "" } b, err := ioutil.ReadAll(r.Body) r.Body.Close() if err != nil { return "" } buf := bytes.NewBuffer(b) _, t, err := image.DecodeConfig(buf) if err != nil { t = "application/octet-stream" } else { t = "image/" + t } w, err := blobstore.Create(c, t) if err != nil { return "" } if _, err := w.Write(b); err != nil { return "" } if w.Close() != nil { return "" } i.Blob, _ = w.Key() su, err := aimage.ServingURL(c, i.Blob, &aimage.ServingURLOptions{Size: 16}) if err != nil { if err = blobstore.Delete(c, i.Blob); err != nil { c.Errorf("blob delete err: %v", err) } return "" } i.Url = su.String() g.Put(i) return i.Url }
func getExternalCover(fr *FileRecord) error { // TODO: Memoize external cover queries. input := &fr.input fd, err := os.Open(filepath.Dir(input.path)) if err != nil { return err } names, err := fd.Readdirnames(-1) fd.Close() if err != nil { return err } input.externalCovers = make(map[string]inputCover) for _, f := range names { if !coverExtList[strings.ToLower(Ext(f))] { continue } fd, err := os.Open(filepath.Join(filepath.Dir(input.path), f)) if err != nil { fr.warning.Print(err) continue } defer fd.Close() st, err := fd.Stat() if err != nil { fr.warning.Print(err) continue } config, format, err := image.DecodeConfig(fd) if err != nil { fr.warning.Print(err) continue } hi := st.Size() if hi > coverChecksumBlock { hi = coverChecksumBlock } buf := [coverChecksumBlock]byte{} _, err = (*fd).ReadAt(buf[:hi], 0) if err != nil && err != io.EOF { fr.warning.Print(err) continue } checksum := fmt.Sprintf("%x", md5.Sum(buf[:hi])) input.externalCovers[f] = inputCover{format: format, width: config.Width, height: config.Height, checksum: checksum} } return nil }
//获取图片信息,主要是高度和宽度 func getImageInfo(path string) (img image.Config, err error) { file, err := os.Open(path) if err != nil { return } defer file.Close() img, _, err = image.DecodeConfig(file) return }
func bytesToImage(imageBytes []byte) (image.Image, image.Config, error) { imageConfig, _, err := image.DecodeConfig(bytes.NewReader(imageBytes)) // _ == format if err != nil { return nil, image.Config{}, err } img, _, err := image.Decode(bytes.NewReader(imageBytes)) // _ == format if err != nil { return nil, image.Config{}, err } return img, imageConfig, nil }
func GetImageSize(path string) image.Config { file, err := os.Open(path) if err != nil { fmt.Fprintln(os.Stderr, err) } img, _, err := image.DecodeConfig(file) if err != nil { fmt.Fprintln(os.Stderr, err) } return img }