예제 #1
1
// 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
}
예제 #2
0
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
}
예제 #3
0
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
}
예제 #4
0
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)
		}
	}
}
예제 #5
0
파일: watermark.go 프로젝트: fcavani/image
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
}
예제 #6
0
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
}
예제 #7
0
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
}
예제 #8
0
파일: image.go 프로젝트: jono-macd/playjunk
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
}
예제 #9
0
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
}
예제 #10
0
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",
	})
}
예제 #11
0
// 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
}
예제 #12
0
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
}
예제 #13
0
파일: manager.go 프로젝트: runningwild/jbot
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
}
예제 #14
0
// 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
}
예제 #15
0
// 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
}
예제 #16
0
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
}
예제 #17
0
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
}
예제 #18
0
// 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
}
예제 #19
0
파일: convert.go 프로젝트: gbersac/nnet
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))
}
예제 #20
0
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))
}
예제 #21
0
파일: texture.go 프로젝트: gdm85/wolfengo
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
}
예제 #22
0
// 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
}
예제 #24
0
// 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
}
예제 #25
0
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
}
예제 #26
0
파일: utils.go 프로젝트: Ranerg/goread
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
}
예제 #27
0
파일: analyzer.go 프로젝트: Ambrevar/Demlo
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
}
예제 #28
0
//获取图片信息,主要是高度和宽度
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
}
예제 #29
0
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
}
예제 #30
0
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
}