Skip to content

Commit

Permalink
media image resize
Browse files Browse the repository at this point in the history
  • Loading branch information
ungerik committed Jul 2, 2012
1 parent a1b16be commit 4e5fbdd
Show file tree
Hide file tree
Showing 5 changed files with 392 additions and 66 deletions.
2 changes: 1 addition & 1 deletion media/functions.go
Expand Up @@ -14,7 +14,7 @@ func ValidUrlFilename(filename string) string {
} else if c >= 'A' && c <= 'Z' {
result[i] = byte(unicode.ToLower(c))
} else {
result[i] = '_'
result[i] = '~'
}
i++
}
Expand Down
86 changes: 55 additions & 31 deletions media/image.go
@@ -1,21 +1,21 @@
package media

import (
"github.com/ungerik/go-start/model"
// "github.com/ungerik/go-start/view"
"bytes"
"image"
"image/png"
_ "image/gif"
_ "code.google.com/p/go.image/tiff"
_ "code.google.com/p/go.image/bmp"
"image/color"
"github.com/ungerik/go-start/model"
// "github.com/ungerik/go-start/view"
)

// NewImage creates a new Image and saves the original version to Config.Backend.
// GIF, TIFF, BMP images will be read, but written as PNG.
func NewImage(file model.File) (*Image, error) {
i, t, err := image.Decode(bytes.NewReader(file.Data))
func NewImage(filename string, data []byte) (*Image, error) {
i, t, err := image.Decode(bytes.NewReader(data))
if err != nil {
return nil, err
}
Expand All @@ -25,23 +25,23 @@ func NewImage(file model.File) (*Image, error) {
if err != nil {
return nil, err
}
file.Data = buf.Bytes()
file.Name += ".png"
i, t, err = image.Decode(bytes.NewReader(file.Data))
data = buf.Bytes()
filename += ".png"
i, t, err = image.Decode(bytes.NewReader(data))
if err != nil {
return nil, err
}
}
result := &Image{
Versions: []ImageVersion{{
Filename: model.String(ValidUrlFilename(file.Name)),
Filename: model.String(ValidUrlFilename(filename)),
ContentType: model.String("image/" + t),
Width: model.Int(i.Bounds().Dx()),
Height: model.Int(i.Bounds().Dy()),
Grayscale: model.Bool(i.ColorModel() == color.GrayModel || i.ColorModel() == color.Gray16Model),
}},
}
err = result.Versions[0].SaveData(file.Data)
err = result.Versions[0].SaveImageData(data)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -75,43 +75,50 @@ func (self *Image) Grayscale() bool {
return self.Versions[0].Grayscale.Get()
}

func (self *Image) outerSizeWithOriginalAspectRatio(width, height int) (int, int) {
originalAspectRatio := float32(self.Width()) / float32(self.Height())
aspectRatio := float32(width) / float32(height)
// AspectRatio returns Width / Height
func (self *Image) AspectRatio() float64 {
return self.Versions[0].AspectRatio()
}

func (self *Image) touchFromOutsideWithOriginalAspectRatio(width, height int) (int, int) {
aspectRatio := float64(width) / float64(height)
originalAspectRatio := self.AspectRatio()
if aspectRatio > originalAspectRatio {
// Wider than original
return width, int(float32(width) / originalAspectRatio)
return width, int(float64(width) / originalAspectRatio)
}
// Heigher than original
return int(float32(height) * originalAspectRatio), height
return int(float64(height) * originalAspectRatio), height
}

func (self *Image) newVersion(width, height int, grayscale bool) (*ImageVersion, error) {
image, err := self.Versions[0].LoadImage()
if err != nil {
return nil, err
}
if image == nil {
}
version := &ImageVersion{
Filename: self.Versions[0].Filename,
ContentType: self.Versions[0].ContentType,
Width: model.Int(width),
Height: model.Int(height),
Grayscale: model.Bool(grayscale),
}
return version, nil
}
// func (self *Image) newVersion(width, height int, grayscale bool) (*ImageVersion, error) {
// image, err := self.Versions[0].LoadImage()
// if err != nil {
// return nil, err
// }
// if image == nil {
// }
// version := &ImageVersion{
// Filename: self.Versions[0].Filename,
// ContentType: self.Versions[0].ContentType,
// Width: model.Int(width),
// Height: model.Int(height),
// Grayscale: model.Bool(grayscale),
// }
// return version, nil
// }

func (self *Image) Version(width, height int, grayscale bool) (*ImageVersion, error) {
if self.Grayscale() {
// Ignore color requests when original image is grayscale
grayscale = true
}

aspectRatio := float64(width) / float64(height)

// If requested image is larger than original size, return original
if width > self.Width() || height > self.Height() {

// todo
}

// Search for exact match
Expand All @@ -123,5 +130,22 @@ func (self *Image) Version(width, height int, grayscale bool) (*ImageVersion, er
}
//

outerWidth, outerHeight := self.touchFromOutsideWithOriginalAspectRatio(width, height)
orig, err := self.Versions[0].LoadImage()
if err != nil {
return nil, err
}
var r image.Rectangle
scaled := ResizeImage(orig, r, width, height)

version := &ImageVersion{
Filename: self.Versions[0].Filename,
ContentType: self.Versions[0].ContentType,
Width: model.Int(width),
Height: model.Int(height),
Grayscale: model.Bool(grayscale),
}
self.Versions = append(self.Versions, *version)

return nil, nil
}
56 changes: 53 additions & 3 deletions media/imageversion.go
Expand Up @@ -2,6 +2,9 @@ package media

import (
"image"
"image/png"
"image/jpeg"
"errors"
"github.com/ungerik/go-start/model"
)

Expand All @@ -18,10 +21,57 @@ func (self *ImageVersion) URL() string {
return View.URL(self.ID.Get(), self.Filename.Get())
}

func (self *ImageVersion) SaveData(data []byte) error {
return nil
// AspectRatio returns Width / Height
func (self *ImageVersion) AspectRatio() float64 {
return float64(self.Width) / float64(self.Height)
}

func (self *ImageVersion) SaveImageData(data []byte) error {
writer, err := Config.Backend.ImageVersionWriter(self)
if err != nil {
return err
}
_, err = writer.Write(data)
if err != nil {
writer.Close()
return err
}
return writer.Close()
}

func (self *ImageVersion) SaveImage(im image.Image) error {
writer, err := Config.Backend.ImageVersionWriter(self)
if err != nil {
return err
}
switch self.ContentType {
case "image/jpeg":
err = jpeg.Encode(writer, im, nil)
case "image/png":
err = png.Encode(writer, im)
default:
return errors.New("Can't save content-type: " + self.ContentType.Get())
}
if err != nil {
writer.Close()
return err
}
return writer.Close()
}

func (self *ImageVersion) LoadImage() (image.Image, error) {
return nil, nil
reader, _, err := Config.Backend.ImageVersionReader(self.ID.Get())
if err != nil {
return nil, err
}
im, _, err := image.Decode(reader)
if err != nil {
reader.Close()
return nil, err
}
err = reader.Close()
if err != nil {
return nil, err
}
return im, nil
}

0 comments on commit 4e5fbdd

Please sign in to comment.