示例#1
0
// makeTestImages generates an RGBA and a grayscale image and returns
// testImages containing the JPEG encoded form as bytes and the expected color
// model of the image when decoded.
func makeTestImages() ([]testImage, error) {
	var ims []testImage
	w := bytes.NewBuffer(nil)
	im1 := image.NewRGBA(image.Rect(0, 0, width, height))
	for i := range im1.Pix {
		switch {
		case i%4 == 3:
			im1.Pix[i] = 255
		default:
			im1.Pix[i] = uint8(i)
		}
	}
	if err := jpeg.Encode(w, im1, nil); err != nil {
		return nil, err
	}
	ims = append(ims, testImage{im: im1, buf: w.Bytes()})

	w = bytes.NewBuffer(nil)
	im2 := image.NewGray(image.Rect(0, 0, width, height))
	for i := range im2.Pix {
		im2.Pix[i] = uint8(i)
	}
	if err := jpeg.Encode(w, im2, nil); err != nil {
		return nil, err
	}
	ims = append(ims, testImage{im: im2, buf: w.Bytes()})
	return ims, nil

}
func testRun(b types.TB, decode decodeFunc) {
	if !fastjpeg.Available() {
		b.Skip("Skipping benchmark, djpeg unavailable.")
	}
	im, _, err := decode(bytes.NewReader(jpegBytes))
	if err != nil {
		b.Fatal(err)
	}
	rect := im.Bounds()
	w, h := 128, 128
	im = resize.Resize(im, rect, w, h)
	err = jpeg.Encode(ioutil.Discard, im, nil)
	if err != nil {
		b.Fatal(err)
	}
}
func init() {
	// Create image with non-uniform color to make decoding more realistic.
	// Solid color jpeg images decode faster than non-uniform images.
	b := new(bytes.Buffer)
	w, h := 4000, 4000
	im := image.NewNRGBA(image.Rect(0, 0, w, h))
	for i := range im.Pix {
		switch {
		case i%4 == 3:
			im.Pix[i] = 255
		default:
			im.Pix[i] = uint8(i)
		}
	}
	if err := jpeg.Encode(b, im, nil); err != nil {
		panic(err)
	}
	jpegBytes = b.Bytes()
}
示例#4
0
// NewUserAttributePhoto creates a user attribute packet
// containing the given images.
func NewUserAttributePhoto(photos ...image.Image) (uat *UserAttribute, err error) {
	uat = new(UserAttribute)
	for _, photo := range photos {
		var buf bytes.Buffer
		// RFC 4880, Section 5.12.1.
		data := []byte{
			0x10, 0x00, // Little-endian image header length (16 bytes)
			0x01,       // Image header version 1
			0x01,       // JPEG
			0, 0, 0, 0, // 12 reserved octets, must be all zero.
			0, 0, 0, 0,
			0, 0, 0, 0}
		if _, err = buf.Write(data); err != nil {
			return
		}
		if err = jpeg.Encode(&buf, photo, nil); err != nil {
			return
		}
		uat.Contents = append(uat.Contents, &OpaqueSubpacket{
			SubType:  UserAttrImageSubpacket,
			Contents: buf.Bytes()})
	}
	return
}
示例#5
0
func (ih *ImageHandler) scaleImage(fileRef blob.Ref) (*formatAndImage, error) {
	fr, err := ih.newFileReader(fileRef)
	if err != nil {
		return nil, err
	}
	defer fr.Close()

	sr := types.NewStatsReader(imageBytesFetchedVar, fr)
	sr, conf, err := imageConfigFromReader(sr)
	if err != nil {
		return nil, err
	}

	// TODO(wathiede): build a size table keyed by conf.ColorModel for
	// common color models for a more exact size estimate.

	// This value is an estimate of the memory required to decode an image.
	// PNGs range from 1-64 bits per pixel (not all of which are supported by
	// the Go standard parser). JPEGs encoded in YCbCr 4:4:4 are 3 byte/pixel.
	// For all other JPEGs this is an overestimate.  For GIFs it is 3x larger
	// than needed.  How accurate this estimate is depends on the mix of
	// images being resized concurrently.
	ramSize := int64(conf.Width) * int64(conf.Height) * 3

	if err = ih.ResizeSem.Acquire(ramSize); err != nil {
		return nil, err
	}
	defer ih.ResizeSem.Release(ramSize)

	i, imConfig, err := images.Decode(sr, &images.DecodeOpts{
		MaxWidth:  ih.MaxWidth,
		MaxHeight: ih.MaxHeight,
	})
	if err != nil {
		return nil, err
	}
	b := i.Bounds()
	format := imConfig.Format

	isSquare := b.Dx() == b.Dy()
	if ih.Square && !isSquare {
		i = squareImage(i)
		b = i.Bounds()
	}

	// Encode as a new image
	var buf bytes.Buffer
	switch format {
	case "png":
		err = png.Encode(&buf, i)
	case "cr2":
		// Recompress CR2 files as JPEG
		format = "jpeg"
		fallthrough
	default:
		err = jpeg.Encode(&buf, i, &jpeg.Options{
			Quality: 90,
		})
	}
	if err != nil {
		return nil, err
	}

	return &formatAndImage{format: format, image: buf.Bytes()}, nil
}