0
Fork 0
mirror of https://github.com/willnorris/imageproxy.git synced 2024-12-16 21:56:43 -05:00
imageproxy/proxy/data.go
Will Norris 0a939cc19d allow more flexibility in specifying options
Options can be specified in any order (size no longer needs to be listed
first), and may be repeated.  Duplicated options overwrite previous
values.  Technically, non-size options could already be repeated... now
size can as well.  There's really not much value to this, it's just an
side-effect of allowing any order.

fixes #5
2013-12-26 13:35:23 -08:00

134 lines
3 KiB
Go

// Copyright 2013 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package data provides common shared data structures for imageproxy.
package proxy
import (
"bytes"
"fmt"
"net/url"
"strconv"
"strings"
"time"
)
// Options specifies transformations that can be performed on a
// requested image.
type Options struct {
Width float64 // requested width, in pixels
Height float64 // requested height, in pixels
// If true, resize the image to fit in the specified dimensions. Image
// will not be cropped, and aspect ratio will be maintained.
Fit bool
// Rotate image the specified degrees counter-clockwise. Valid values are 90, 180, 270.
Rotate int
FlipVertical bool
FlipHorizontal bool
}
func (o Options) String() string {
buf := new(bytes.Buffer)
fmt.Fprintf(buf, "%vx%v", o.Width, o.Height)
if o.Fit {
buf.WriteString(",fit")
}
if o.Rotate != 0 {
fmt.Fprintf(buf, ",r%d", o.Rotate)
}
if o.FlipVertical {
buf.WriteString(",fv")
}
if o.FlipHorizontal {
buf.WriteString(",fh")
}
return buf.String()
}
func ParseOptions(str string) *Options {
o := new(Options)
parts := strings.Split(str, ",")
for _, part := range parts {
if part == "fit" {
o.Fit = true
continue
}
if part == "fv" {
o.FlipVertical = true
continue
}
if part == "fh" {
o.FlipHorizontal = true
continue
}
if len(part) > 2 && part[:1] == "r" {
o.Rotate, _ = strconv.Atoi(part[1:])
continue
}
if strings.ContainsRune(part, 'x') {
var h, w string
size := strings.SplitN(part, "x", 2)
w = size[0]
if len(size) > 1 {
h = size[1]
} else {
h = w
}
if w != "" {
o.Width, _ = strconv.ParseFloat(w, 64)
}
if h != "" {
o.Height, _ = strconv.ParseFloat(h, 64)
}
continue
}
if size, err := strconv.ParseFloat(part, 64); err == nil {
o.Width = size
o.Height = size
continue
}
}
return o
}
type Request struct {
URL *url.URL // URL of the image to proxy
Options *Options // Image transformation to perform
}
// Image represents a remote image that is being proxied. It tracks where
// the image was originally retrieved from and how long the image can be cached.
type Image struct {
// URL of original remote image.
URL string
// Expires is the cache expiration time for the original image, as
// returned by the remote server.
Expires time.Time
// Etag returned from server when fetching image.
Etag string
// Bytes contains the actual image.
Bytes []byte
}