mirror of https://mirror.trustie.net/root/bimg.git
feat(version): v1 release. see history for details
This commit is contained in:
parent
a0fc602e69
commit
c57a8c1320
15
.travis.yml
15
.travis.yml
|
@ -1,10 +1,19 @@
|
|||
language: go
|
||||
|
||||
go:
|
||||
- 1.6
|
||||
- 1.5
|
||||
- 1.4
|
||||
- 1.3
|
||||
- release
|
||||
- tip
|
||||
|
||||
script:
|
||||
- diff -u <(echo -n) <(gofmt -s -d ./)
|
||||
- diff -u <(echo -n) <(go vet ./)
|
||||
- diff -u <(echo -n) <(golint ./)
|
||||
- go test -v -race ./...
|
||||
- go test -v -race -covermode=atomic -coverprofile=coverage.out
|
||||
|
||||
after_success:
|
||||
- goveralls -coverprofile=coverage.out -service=travis-ci
|
||||
|
||||
before_install:
|
||||
- curl -s https://raw.githubusercontent.com/lovell/sharp/master/preinstall.sh | sudo bash -
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
## 1.0.0 / 21-04-2016
|
||||
|
||||
- refactor(api): breaking changes: normalize public members to follow Go naming idioms.
|
||||
- feat(version): bump to major version. API contract won't be compromised in `v1`.
|
||||
- feat(docs): add missing inline godoc documentation.
|
|
@ -11,6 +11,9 @@ If you're looking for an HTTP based image processing solution, see [imaginary](h
|
|||
|
||||
bimg was heavily inspired in [sharp](https://github.com/lovell/sharp), its homologous package built for [node.js](http://nodejs.org).
|
||||
|
||||
**v1 notice**: `bimg` introduces some minor breaking changes in `v1` release.
|
||||
If you're using `gopkg.in`, you can still rely in the `v0` without worrying about breaking changes.
|
||||
|
||||
## Contents
|
||||
|
||||
- [Supported image operations](#supported-image-operations)
|
||||
|
|
5
debug.go
5
debug.go
|
@ -1,5 +0,0 @@
|
|||
package bimg
|
||||
|
||||
import . "github.com/tj/go-debug"
|
||||
|
||||
var debug = Debug("bimg")
|
4
file.go
4
file.go
|
@ -2,10 +2,14 @@ package bimg
|
|||
|
||||
import "io/ioutil"
|
||||
|
||||
// Read reads all the content of the given file path
|
||||
// and returns it as byte buffer.
|
||||
func Read(path string) ([]byte, error) {
|
||||
return ioutil.ReadFile(path)
|
||||
}
|
||||
|
||||
// Write writes the given byte buffer into disk
|
||||
// to the given file path.
|
||||
func Write(path string, buf []byte) error {
|
||||
return ioutil.WriteFile(path, buf, 0644)
|
||||
}
|
||||
|
|
57
image.go
57
image.go
|
@ -1,16 +1,16 @@
|
|||
package bimg
|
||||
|
||||
// Image encapsulates the whole image buffer
|
||||
// Image provides a simple method DSL to transform a given image as byte buffer.
|
||||
type Image struct {
|
||||
buffer []byte
|
||||
}
|
||||
|
||||
// Creates a new image
|
||||
// NewImage creates a new Image struct with method DSL.
|
||||
func NewImage(buf []byte) *Image {
|
||||
return &Image{buf}
|
||||
}
|
||||
|
||||
// Resize the image to fixed width and height
|
||||
// Resize resizes the image to fixed width and height.
|
||||
func (i *Image) Resize(width, height int) ([]byte, error) {
|
||||
options := Options{
|
||||
Width: width,
|
||||
|
@ -20,7 +20,7 @@ func (i *Image) Resize(width, height int) ([]byte, error) {
|
|||
return i.Process(options)
|
||||
}
|
||||
|
||||
// Force resize with custom size (aspect ratio won't be maintained)
|
||||
// ForceResize resizes with custom size (aspect ratio won't be maintained).
|
||||
func (i *Image) ForceResize(width, height int) ([]byte, error) {
|
||||
options := Options{
|
||||
Width: width,
|
||||
|
@ -30,7 +30,7 @@ func (i *Image) ForceResize(width, height int) ([]byte, error) {
|
|||
return i.Process(options)
|
||||
}
|
||||
|
||||
// Resize the image to fixed width and height with additional crop transformation
|
||||
// ResizeAndCrop resizes the image to fixed width and height with additional crop transformation.
|
||||
func (i *Image) ResizeAndCrop(width, height int) ([]byte, error) {
|
||||
options := Options{
|
||||
Width: width,
|
||||
|
@ -41,7 +41,7 @@ func (i *Image) ResizeAndCrop(width, height int) ([]byte, error) {
|
|||
return i.Process(options)
|
||||
}
|
||||
|
||||
// Extract area from the by X/Y axis
|
||||
// Extract area from the by X/Y axis in the current image.
|
||||
func (i *Image) Extract(top, left, width, height int) ([]byte, error) {
|
||||
options := Options{
|
||||
Top: top,
|
||||
|
@ -57,7 +57,7 @@ func (i *Image) Extract(top, left, width, height int) ([]byte, error) {
|
|||
return i.Process(options)
|
||||
}
|
||||
|
||||
// Enlarge the image by width and height. Aspect ratio is maintained
|
||||
// Enlarge enlarges the image by width and height. Aspect ratio is maintained.
|
||||
func (i *Image) Enlarge(width, height int) ([]byte, error) {
|
||||
options := Options{
|
||||
Width: width,
|
||||
|
@ -67,7 +67,7 @@ func (i *Image) Enlarge(width, height int) ([]byte, error) {
|
|||
return i.Process(options)
|
||||
}
|
||||
|
||||
// Enlarge the image by width and height with additional crop transformation
|
||||
// EnlargeAndCrop enlarges the image by width and height with additional crop transformation.
|
||||
func (i *Image) EnlargeAndCrop(width, height int) ([]byte, error) {
|
||||
options := Options{
|
||||
Width: width,
|
||||
|
@ -78,7 +78,7 @@ func (i *Image) EnlargeAndCrop(width, height int) ([]byte, error) {
|
|||
return i.Process(options)
|
||||
}
|
||||
|
||||
// Crop the image to the exact size specified
|
||||
// Crop crops the image to the exact size specified.
|
||||
func (i *Image) Crop(width, height int, gravity Gravity) ([]byte, error) {
|
||||
options := Options{
|
||||
Width: width,
|
||||
|
@ -89,7 +89,7 @@ func (i *Image) Crop(width, height int, gravity Gravity) ([]byte, error) {
|
|||
return i.Process(options)
|
||||
}
|
||||
|
||||
// Crop an image by width (auto height)
|
||||
// CropByWidth crops an image by width only param (auto height).
|
||||
func (i *Image) CropByWidth(width int) ([]byte, error) {
|
||||
options := Options{
|
||||
Width: width,
|
||||
|
@ -98,7 +98,7 @@ func (i *Image) CropByWidth(width int) ([]byte, error) {
|
|||
return i.Process(options)
|
||||
}
|
||||
|
||||
// Crop an image by height (auto width)
|
||||
// CropByHeight crops an image by height (auto width).
|
||||
func (i *Image) CropByHeight(height int) ([]byte, error) {
|
||||
options := Options{
|
||||
Height: height,
|
||||
|
@ -107,7 +107,7 @@ func (i *Image) CropByHeight(height int) ([]byte, error) {
|
|||
return i.Process(options)
|
||||
}
|
||||
|
||||
// Thumbnail the image by the a given width by aspect ratio 4:4
|
||||
// Thumbnail creates a thumbnail of the image by the a given width by aspect ratio 4:4.
|
||||
func (i *Image) Thumbnail(pixels int) ([]byte, error) {
|
||||
options := Options{
|
||||
Width: pixels,
|
||||
|
@ -118,50 +118,52 @@ func (i *Image) Thumbnail(pixels int) ([]byte, error) {
|
|||
return i.Process(options)
|
||||
}
|
||||
|
||||
// Add text as watermark on the given image
|
||||
// Watermark adds text as watermark on the given image.
|
||||
func (i *Image) Watermark(w Watermark) ([]byte, error) {
|
||||
options := Options{Watermark: w}
|
||||
return i.Process(options)
|
||||
}
|
||||
|
||||
// Zoom the image by the given factor.
|
||||
// You should probably call Extract() before
|
||||
// Zoom zooms the image by the given factor.
|
||||
// You should probably call Extract() before.
|
||||
func (i *Image) Zoom(factor int) ([]byte, error) {
|
||||
options := Options{Zoom: factor}
|
||||
return i.Process(options)
|
||||
}
|
||||
|
||||
// Rotate the image by given angle degrees (0, 90, 180 or 270)
|
||||
// Rotate rotates the image by given angle degrees (0, 90, 180 or 270).
|
||||
func (i *Image) Rotate(a Angle) ([]byte, error) {
|
||||
options := Options{Rotate: a}
|
||||
return i.Process(options)
|
||||
}
|
||||
|
||||
// Flip the image about the vertical Y axis
|
||||
// Flip flips the image about the vertical Y axis.
|
||||
func (i *Image) Flip() ([]byte, error) {
|
||||
options := Options{Flip: true}
|
||||
return i.Process(options)
|
||||
}
|
||||
|
||||
// Flop the image about the horizontal X axis
|
||||
// Flop flops the image about the horizontal X axis.
|
||||
func (i *Image) Flop() ([]byte, error) {
|
||||
options := Options{Flop: true}
|
||||
return i.Process(options)
|
||||
}
|
||||
|
||||
// Convert image to another format
|
||||
// Convert converts image to another format.
|
||||
func (i *Image) Convert(t ImageType) ([]byte, error) {
|
||||
options := Options{Type: t}
|
||||
return i.Process(options)
|
||||
}
|
||||
|
||||
// Colour space conversion
|
||||
// Colourspace performs a color space conversion bsaed on the given interpretation.
|
||||
func (i *Image) Colourspace(c Interpretation) ([]byte, error) {
|
||||
options := Options{Interpretation: c}
|
||||
return i.Process(options)
|
||||
}
|
||||
|
||||
// Transform the image by custom options
|
||||
// Process processes the image based on the given transformation options,
|
||||
// talking with libvips bindings accordingly and returning the resultant
|
||||
// image buffer.
|
||||
func (i *Image) Process(o Options) ([]byte, error) {
|
||||
image, err := Resize(i.buffer, o)
|
||||
if err != nil {
|
||||
|
@ -171,33 +173,34 @@ func (i *Image) Process(o Options) ([]byte, error) {
|
|||
return image, nil
|
||||
}
|
||||
|
||||
// Get image metadata (size, alpha channel, profile, EXIF rotation)
|
||||
// Metadata returns the image metadata (size, alpha channel, profile, EXIF rotation).
|
||||
func (i *Image) Metadata() (ImageMetadata, error) {
|
||||
return Metadata(i.buffer)
|
||||
}
|
||||
|
||||
// Get the image interpretation type
|
||||
// Interpretation gets the image interpretation type.
|
||||
// See: http://www.vips.ecs.soton.ac.uk/supported/current/doc/html/libvips/VipsImage.html#VipsInterpretation
|
||||
func (i *Image) Interpretation() (Interpretation, error) {
|
||||
return ImageInterpretation(i.buffer)
|
||||
}
|
||||
|
||||
// Check if the current image has a valid colourspace
|
||||
// ColourspaceIsSupported checks if the current image
|
||||
// color space is supported.
|
||||
func (i *Image) ColourspaceIsSupported() (bool, error) {
|
||||
return ColourspaceIsSupported(i.buffer)
|
||||
}
|
||||
|
||||
// Get image type format (jpeg, png, webp, tiff)
|
||||
// Type returns the image type format (jpeg, png, webp, tiff).
|
||||
func (i *Image) Type() string {
|
||||
return DetermineImageTypeName(i.buffer)
|
||||
}
|
||||
|
||||
// Get image size
|
||||
// Size returns the image size as form of width and height pixels.
|
||||
func (i *Image) Size() (ImageSize, error) {
|
||||
return Size(i.buffer)
|
||||
}
|
||||
|
||||
// Get image buffer
|
||||
// Image returns the current resultant image image buffer.
|
||||
func (i *Image) Image() []byte {
|
||||
return i.buffer
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@ func TestImageEnlargeAndCrop(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestImageCrop(t *testing.T) {
|
||||
buf, err := initImage("test.jpg").Crop(800, 600, NORTH)
|
||||
buf, err := initImage("test.jpg").Crop(800, 600, GravityNorth)
|
||||
if err != nil {
|
||||
t.Errorf("Cannot process the image: %s", err)
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ func TestImageThumbnail(t *testing.T) {
|
|||
|
||||
func TestImageWatermark(t *testing.T) {
|
||||
image := initImage("test.jpg")
|
||||
_, err := image.Crop(800, 600, NORTH)
|
||||
_, err := image.Crop(800, 600, GravityNorth)
|
||||
if err != nil {
|
||||
t.Errorf("Cannot process the image: %#v", err)
|
||||
}
|
||||
|
@ -178,7 +178,7 @@ func TestImageWatermark(t *testing.T) {
|
|||
|
||||
func TestImageWatermarkNoReplicate(t *testing.T) {
|
||||
image := initImage("test.jpg")
|
||||
_, err := image.Crop(800, 600, NORTH)
|
||||
_, err := image.Crop(800, 600, GravityNorth)
|
||||
if err != nil {
|
||||
t.Errorf("Cannot process the image: %s", err)
|
||||
}
|
||||
|
@ -294,7 +294,7 @@ func TestInterpretation(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Errorf("Cannot process the image: %#v", err)
|
||||
}
|
||||
if interpretation != INTERPRETATION_sRGB {
|
||||
if interpretation != InterpretationSRGB {
|
||||
t.Errorf("Invalid interpretation: %d", interpretation)
|
||||
}
|
||||
}
|
||||
|
@ -304,8 +304,8 @@ func TestImageColourspace(t *testing.T) {
|
|||
file string
|
||||
interpretation Interpretation
|
||||
}{
|
||||
{"test.jpg", INTERPRETATION_sRGB},
|
||||
{"test.jpg", INTERPRETATION_B_W},
|
||||
{"test.jpg", InterpretationSRGB},
|
||||
{"test.jpg", InterpretationBW},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
|
10
metadata.go
10
metadata.go
|
@ -12,7 +12,7 @@ type ImageSize struct {
|
|||
Height int
|
||||
}
|
||||
|
||||
// ImageMedatada represents the basic metadata fields
|
||||
// ImageMetadata represents the basic metadata fields
|
||||
type ImageMetadata struct {
|
||||
Orientation int
|
||||
Channels int
|
||||
|
@ -24,7 +24,7 @@ type ImageMetadata struct {
|
|||
Size ImageSize
|
||||
}
|
||||
|
||||
// Get the image size by width and height pixels
|
||||
// Size returns the image size by width and height pixels.
|
||||
func Size(buf []byte) (ImageSize, error) {
|
||||
metadata, err := Metadata(buf)
|
||||
if err != nil {
|
||||
|
@ -37,18 +37,18 @@ func Size(buf []byte) (ImageSize, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
// Check in the image colourspace is supported by libvips
|
||||
// ColourspaceIsSupported checks if the image colourspace is supported by libvips.
|
||||
func ColourspaceIsSupported(buf []byte) (bool, error) {
|
||||
return vipsColourspaceIsSupportedBuffer(buf)
|
||||
}
|
||||
|
||||
// Get the image interpretation type
|
||||
// ImageInterpretation returns the image interpretation type.
|
||||
// See: http://www.vips.ecs.soton.ac.uk/supported/current/doc/html/libvips/VipsImage.html#VipsInterpretation
|
||||
func ImageInterpretation(buf []byte) (Interpretation, error) {
|
||||
return vipsInterpretationBuffer(buf)
|
||||
}
|
||||
|
||||
// Extract the image metadata (size, type, alpha channel, profile, EXIF orientation...)
|
||||
// Metadata returns the image metadata (size, type, alpha channel, profile, EXIF orientation...).
|
||||
func Metadata(buf []byte) (ImageMetadata, error) {
|
||||
defer C.vips_thread_shutdown()
|
||||
|
||||
|
|
|
@ -72,9 +72,9 @@ func TestImageInterpretation(t *testing.T) {
|
|||
name string
|
||||
interpretation Interpretation
|
||||
}{
|
||||
{"test.jpg", INTERPRETATION_sRGB},
|
||||
{"test.png", INTERPRETATION_sRGB},
|
||||
{"test.webp", INTERPRETATION_sRGB},
|
||||
{"test.jpg", InterpretationSRGB},
|
||||
{"test.png", InterpretationSRGB},
|
||||
{"test.webp", InterpretationSRGB},
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
|
|
102
options.go
102
options.go
|
@ -7,83 +7,115 @@ package bimg
|
|||
import "C"
|
||||
|
||||
const (
|
||||
QUALITY = 80
|
||||
MAX_SIZE = 16383
|
||||
// Quality defines the default JPEG quality to be used.
|
||||
Quality = 80
|
||||
// MaxSize defines the maximum pixels width or height supported.
|
||||
MaxSize = 16383
|
||||
)
|
||||
|
||||
// Gravity represents the image gravity value.
|
||||
type Gravity int
|
||||
|
||||
const (
|
||||
CENTRE Gravity = iota
|
||||
NORTH
|
||||
EAST
|
||||
SOUTH
|
||||
WEST
|
||||
// GravityCentre represents the centre value used for image gravity orientation.
|
||||
GravityCentre Gravity = iota
|
||||
// GravityNorth represents the north value used for image gravity orientation.
|
||||
GravityNorth
|
||||
// GravityEast represents the east value used for image gravity orientation.
|
||||
GravityEast
|
||||
// GravitySouth represents the south value used for image gravity orientation.
|
||||
GravitySouth
|
||||
// GravityWest represents the west value used for image gravity orientation.
|
||||
GravityWest
|
||||
)
|
||||
|
||||
// Interpolator represents the image interpolation value.
|
||||
type Interpolator int
|
||||
|
||||
const (
|
||||
BICUBIC Interpolator = iota
|
||||
BILINEAR
|
||||
NOHALO
|
||||
// Bicubic interpolation value.
|
||||
Bicubic Interpolator = iota
|
||||
// Bilinear interpolation value.
|
||||
Bilinear
|
||||
// Nohalo interpolation value.
|
||||
Nohalo
|
||||
)
|
||||
|
||||
var interpolations = map[Interpolator]string{
|
||||
BICUBIC: "bicubic",
|
||||
BILINEAR: "bilinear",
|
||||
NOHALO: "nohalo",
|
||||
Bicubic: "bicubic",
|
||||
Bilinear: "bilinear",
|
||||
Nohalo: "nohalo",
|
||||
}
|
||||
|
||||
func (i Interpolator) String() string {
|
||||
return interpolations[i]
|
||||
}
|
||||
|
||||
// Angle represents the image rotation angle value.
|
||||
type Angle int
|
||||
|
||||
const (
|
||||
D0 Angle = 0
|
||||
D90 Angle = 90
|
||||
// D0 represents the rotation angle 0 degrees.
|
||||
D0 Angle = 0
|
||||
// D90 represents the rotation angle 90 degrees.
|
||||
D90 Angle = 90
|
||||
// D180 represents the rotation angle 180 degrees.
|
||||
D180 Angle = 180
|
||||
// D270 represents the rotation angle 270 degrees.
|
||||
D270 Angle = 270
|
||||
)
|
||||
|
||||
// Direction represents the image direction value.
|
||||
type Direction int
|
||||
|
||||
const (
|
||||
HORIZONTAL Direction = C.VIPS_DIRECTION_HORIZONTAL
|
||||
VERTICAL Direction = C.VIPS_DIRECTION_VERTICAL
|
||||
// Horizontal represents the orizontal image direction value.
|
||||
Horizontal Direction = C.VIPS_DIRECTION_HORIZONTAL
|
||||
// Vertical represents the vertical image direction value.
|
||||
Vertical Direction = C.VIPS_DIRECTION_VERTICAL
|
||||
)
|
||||
|
||||
// Image interpretation type
|
||||
// Interpretation represents the image interpretation type.
|
||||
// See: http://www.vips.ecs.soton.ac.uk/supported/current/doc/html/libvips/VipsImage.html#VipsInterpretation
|
||||
type Interpretation int
|
||||
|
||||
const (
|
||||
INTERPRETATION_ERROR Interpretation = C.VIPS_INTERPRETATION_ERROR
|
||||
INTERPRETATION_MULTIBAND Interpretation = C.VIPS_INTERPRETATION_MULTIBAND
|
||||
INTERPRETATION_B_W Interpretation = C.VIPS_INTERPRETATION_B_W
|
||||
INTERPRETATION_CMYK Interpretation = C.VIPS_INTERPRETATION_CMYK
|
||||
INTERPRETATION_RGB Interpretation = C.VIPS_INTERPRETATION_RGB
|
||||
INTERPRETATION_sRGB Interpretation = C.VIPS_INTERPRETATION_sRGB
|
||||
INTERPRETATION_RGB16 Interpretation = C.VIPS_INTERPRETATION_RGB16
|
||||
INTERPRETATION_GREY16 Interpretation = C.VIPS_INTERPRETATION_GREY16
|
||||
INTERPRETATION_scRGB Interpretation = C.VIPS_INTERPRETATION_scRGB
|
||||
INTERPRETATION_LAB Interpretation = C.VIPS_INTERPRETATION_LAB
|
||||
INTERPRETATION_XYZ Interpretation = C.VIPS_INTERPRETATION_XYZ
|
||||
// InterpretationError points to the libvips interpretation error type.
|
||||
InterpretationError Interpretation = C.VIPS_INTERPRETATION_ERROR
|
||||
// InterpretationMultiband points to its libvips interpretation equivalent type.
|
||||
InterpretationMultiband Interpretation = C.VIPS_INTERPRETATION_MULTIBAND
|
||||
// InterpretationBW points to its libvips interpretation equivalent type.
|
||||
InterpretationBW Interpretation = C.VIPS_INTERPRETATION_B_W
|
||||
// InterpretationCMYK points to its libvips interpretation equivalent type.
|
||||
InterpretationCMYK Interpretation = C.VIPS_INTERPRETATION_CMYK
|
||||
// InterpretationRGB points to its libvips interpretation equivalent type.
|
||||
InterpretationRGB Interpretation = C.VIPS_INTERPRETATION_RGB
|
||||
// InterpretationSRGB points to its libvips interpretation equivalent type.
|
||||
InterpretationSRGB Interpretation = C.VIPS_INTERPRETATION_sRGB
|
||||
// InterpretationRGB16 points to its libvips interpretation equivalent type.
|
||||
InterpretationRGB16 Interpretation = C.VIPS_INTERPRETATION_RGB16
|
||||
// InterpretationGREY16 points to its libvips interpretation equivalent type.
|
||||
InterpretationGREY16 Interpretation = C.VIPS_INTERPRETATION_GREY16
|
||||
// InterpretationScRGB points to its libvips interpretation equivalent type.
|
||||
InterpretationScRGB Interpretation = C.VIPS_INTERPRETATION_scRGB
|
||||
// InterpretationLAB points to its libvips interpretation equivalent type.
|
||||
InterpretationLAB Interpretation = C.VIPS_INTERPRETATION_LAB
|
||||
// InterpretationXYZ points to its libvips interpretation equivalent type.
|
||||
InterpretationXYZ Interpretation = C.VIPS_INTERPRETATION_XYZ
|
||||
)
|
||||
|
||||
const WATERMARK_FONT = "sans 10"
|
||||
// WatermarkFont defines the default watermark font to be used.
|
||||
var WatermarkFont = "sans 10"
|
||||
|
||||
// Color represents a traditional RGB color scheme
|
||||
// Color represents a traditional RGB color scheme.
|
||||
type Color struct {
|
||||
R, G, B uint8
|
||||
}
|
||||
|
||||
// Shortcut to black RGB color representation
|
||||
// ColorBlack is a shortcut to black RGB color representation.
|
||||
var ColorBlack = Color{0, 0, 0}
|
||||
|
||||
// Text-based watermark configuration
|
||||
// Watermark represents the text-based watermark supported options.
|
||||
type Watermark struct {
|
||||
Width int
|
||||
DPI int
|
||||
|
@ -95,11 +127,13 @@ type Watermark struct {
|
|||
Background Color
|
||||
}
|
||||
|
||||
// GaussianBlur represents the gaussian image transformation values.
|
||||
type GaussianBlur struct {
|
||||
Sigma float64
|
||||
MinAmpl float64
|
||||
}
|
||||
|
||||
// Sharpen represents the image sharp transformation options.
|
||||
type Sharpen struct {
|
||||
Radius int
|
||||
X1 float64
|
||||
|
@ -109,7 +143,7 @@ type Sharpen struct {
|
|||
M2 float64
|
||||
}
|
||||
|
||||
// Supported image transformation options
|
||||
// Options represents the supported image transformation options.
|
||||
type Options struct {
|
||||
Height int
|
||||
Width int
|
||||
|
|
22
resize.go
22
resize.go
|
@ -11,6 +11,8 @@ import (
|
|||
"math"
|
||||
)
|
||||
|
||||
// Resize is used to transform a given image as byte buffer
|
||||
// with the passed options.
|
||||
func Resize(buf []byte, o Options) ([]byte, error) {
|
||||
defer C.vips_thread_shutdown()
|
||||
|
||||
|
@ -131,7 +133,7 @@ func Resize(buf []byte, o Options) ([]byte, error) {
|
|||
|
||||
func applyDefaults(o Options, imageType ImageType) Options {
|
||||
if o.Quality == 0 {
|
||||
o.Quality = QUALITY
|
||||
o.Quality = Quality
|
||||
}
|
||||
if o.Compression == 0 {
|
||||
o.Compression = 6
|
||||
|
@ -140,7 +142,7 @@ func applyDefaults(o Options, imageType ImageType) Options {
|
|||
o.Type = imageType
|
||||
}
|
||||
if o.Interpretation == 0 {
|
||||
o.Interpretation = INTERPRETATION_sRGB
|
||||
o.Interpretation = InterpretationSRGB
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
@ -224,7 +226,7 @@ func applyEffects(image *C.VipsImage, o Options) (*C.VipsImage, error) {
|
|||
}
|
||||
|
||||
func extractOrEmbedImage(image *C.VipsImage, o Options) (*C.VipsImage, error) {
|
||||
var err error = nil
|
||||
var err error
|
||||
inWidth := int(image.Xsize)
|
||||
inHeight := int(image.Ysize)
|
||||
|
||||
|
@ -278,9 +280,9 @@ func rotateAndFlipImage(image *C.VipsImage, o Options) (*C.VipsImage, bool, erro
|
|||
}
|
||||
|
||||
if o.Flip {
|
||||
direction = HORIZONTAL
|
||||
direction = Horizontal
|
||||
} else if o.Flop {
|
||||
direction = VERTICAL
|
||||
direction = Vertical
|
||||
}
|
||||
|
||||
if direction != -1 {
|
||||
|
@ -298,7 +300,7 @@ func watermakImage(image *C.VipsImage, w Watermark) (*C.VipsImage, error) {
|
|||
|
||||
// Defaults
|
||||
if w.Font == "" {
|
||||
w.Font = WATERMARK_FONT
|
||||
w.Font = WatermarkFont
|
||||
}
|
||||
if w.Width == 0 {
|
||||
w.Width = int(math.Floor(float64(image.Xsize / 6)))
|
||||
|
@ -420,15 +422,15 @@ func calculateCrop(inWidth, inHeight, outWidth, outHeight int, gravity Gravity)
|
|||
left, top := 0, 0
|
||||
|
||||
switch gravity {
|
||||
case NORTH:
|
||||
case GravityNorth:
|
||||
left = (inWidth - outWidth + 1) / 2
|
||||
case EAST:
|
||||
case GravityEast:
|
||||
left = inWidth - outWidth
|
||||
top = (inHeight - outHeight + 1) / 2
|
||||
case SOUTH:
|
||||
case GravitySouth:
|
||||
left = (inWidth - outWidth + 1) / 2
|
||||
top = inHeight - outHeight
|
||||
case WEST:
|
||||
case GravityWest:
|
||||
top = (inHeight - outHeight + 1) / 2
|
||||
default:
|
||||
left = (inWidth - outWidth + 1) / 2
|
||||
|
|
18
type.go
18
type.go
|
@ -1,17 +1,24 @@
|
|||
package bimg
|
||||
|
||||
// ImageType represents an image type value.
|
||||
type ImageType int
|
||||
|
||||
const (
|
||||
// UNKNOWN represents an unknow image type value.
|
||||
UNKNOWN ImageType = iota
|
||||
// JPEG represents the JPEG image type.
|
||||
JPEG
|
||||
// WEBP represents the WEBP image type.
|
||||
WEBP
|
||||
// PNG represents the PNG image type.
|
||||
PNG
|
||||
// TIFF represents the TIFF image type.
|
||||
TIFF
|
||||
// MAGICK represents the libmagick compatible genetic image type.
|
||||
MAGICK
|
||||
)
|
||||
|
||||
// Pairs of image type and its name
|
||||
// ImageTypes stores as pairs of image types supported and its alias names.
|
||||
var ImageTypes = map[ImageType]string{
|
||||
JPEG: "jpeg",
|
||||
PNG: "png",
|
||||
|
@ -20,22 +27,22 @@ var ImageTypes = map[ImageType]string{
|
|||
MAGICK: "magick",
|
||||
}
|
||||
|
||||
// Determines the image type format (jpeg, png, webp or tiff)
|
||||
// DetermineImageType determines the image type format (jpeg, png, webp or tiff)
|
||||
func DetermineImageType(buf []byte) ImageType {
|
||||
return vipsImageType(buf)
|
||||
}
|
||||
|
||||
// Determines the image type format by name (jpeg, png, webp or tiff)
|
||||
// DetermineImageTypeName determines the image type format by name (jpeg, png, webp or tiff)
|
||||
func DetermineImageTypeName(buf []byte) string {
|
||||
return ImageTypeName(vipsImageType(buf))
|
||||
}
|
||||
|
||||
// Check if a given image type is supported
|
||||
// IsTypeSupported checks if a given image type is supported
|
||||
func IsTypeSupported(t ImageType) bool {
|
||||
return ImageTypes[t] != ""
|
||||
}
|
||||
|
||||
// Check if a given image type name is supported
|
||||
// IsTypeNameSupported checks if a given image type name is supported
|
||||
func IsTypeNameSupported(t string) bool {
|
||||
for _, name := range ImageTypes {
|
||||
if name == t {
|
||||
|
@ -45,6 +52,7 @@ func IsTypeNameSupported(t string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// ImageTypeName is used to get the human friendly name of an image format.
|
||||
func ImageTypeName(t ImageType) string {
|
||||
imageType := ImageTypes[t]
|
||||
if imageType == "" {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
package bimg
|
||||
|
||||
const Version = "0.1.24"
|
||||
// Version represents the current package semantic version.
|
||||
const Version = "1.0.0"
|
||||
|
|
27
vips.go
27
vips.go
|
@ -14,11 +14,18 @@ import (
|
|||
"strings"
|
||||
"sync"
|
||||
"unsafe"
|
||||
|
||||
d "github.com/tj/go-debug"
|
||||
)
|
||||
|
||||
// Current libvips version
|
||||
// debug is internally used to
|
||||
var debug = d.Debug("bimg")
|
||||
|
||||
// VipsVersion exposes the current libvips semantic version
|
||||
const VipsVersion = string(C.VIPS_VERSION)
|
||||
|
||||
// HasMagickSupport exposes if the current libvips compilation
|
||||
// supports libmagick bindings.
|
||||
const HasMagickSupport = int(C.VIPS_MAGICK_SUPPORT) == 1
|
||||
|
||||
const (
|
||||
|
@ -31,12 +38,14 @@ var (
|
|||
initialized bool
|
||||
)
|
||||
|
||||
// VipsMemoryInfo represents the memory stats provided by libvips.
|
||||
type VipsMemoryInfo struct {
|
||||
Memory int64
|
||||
MemoryHighwater int64
|
||||
Allocations int64
|
||||
}
|
||||
|
||||
// vipsSaveOptions represents the internal option used to talk with libvips.
|
||||
type vipsSaveOptions struct {
|
||||
Quality int
|
||||
Compression int
|
||||
|
@ -64,8 +73,8 @@ func init() {
|
|||
Initialize()
|
||||
}
|
||||
|
||||
// Explicit thread-safe start of libvips.
|
||||
// Only call this function if you previously shutdown libvips
|
||||
// Initialize is used to explicitly start libvips in thread-safe way.
|
||||
// Only call this function if you have previously turned off libvips.
|
||||
func Initialize() {
|
||||
if C.VIPS_MAJOR_VERSION <= 7 && C.VIPS_MINOR_VERSION < 40 {
|
||||
panic("unsupported libvips version!")
|
||||
|
@ -99,7 +108,7 @@ func Initialize() {
|
|||
initialized = true
|
||||
}
|
||||
|
||||
// Thread-safe function to shutdown libvips.
|
||||
// Shutdown is used to shutdown libvips in a thread-safe way.
|
||||
// You can call this to drop caches as well.
|
||||
// If libvips was already initialized, the function is no-op
|
||||
func Shutdown() {
|
||||
|
@ -112,12 +121,12 @@ func Shutdown() {
|
|||
}
|
||||
}
|
||||
|
||||
// Output to stdout vips collected data. Useful for debugging
|
||||
// VipsDebugInfo outputs to stdout libvips collected data. Useful for debugging.
|
||||
func VipsDebugInfo() {
|
||||
C.im__print_all()
|
||||
}
|
||||
|
||||
// Get memory info stats from vips (cache size, memory allocs...)
|
||||
// VipsMemory gets memory info stats from libvips (cache size, memory allocs...)
|
||||
func VipsMemory() VipsMemoryInfo {
|
||||
return VipsMemoryInfo{
|
||||
Memory: int64(C.vips_tracked_get_mem()),
|
||||
|
@ -246,7 +255,7 @@ func vipsColourspaceIsSupported(image *C.VipsImage) bool {
|
|||
func vipsInterpretationBuffer(buf []byte) (Interpretation, error) {
|
||||
image, _, err := vipsRead(buf)
|
||||
if err != nil {
|
||||
return INTERPRETATION_ERROR, err
|
||||
return InterpretationError, err
|
||||
}
|
||||
C.g_object_unref(C.gpointer(image))
|
||||
return vipsInterpretation(image), nil
|
||||
|
@ -284,7 +293,7 @@ func vipsPreSave(image *C.VipsImage, o *vipsSaveOptions) (*C.VipsImage, error) {
|
|||
|
||||
// Use a default interpretation and cast it to C type
|
||||
if o.Interpretation == 0 {
|
||||
o.Interpretation = INTERPRETATION_sRGB
|
||||
o.Interpretation = InterpretationSRGB
|
||||
}
|
||||
interpretation := C.VipsInterpretation(o.Interpretation)
|
||||
|
||||
|
@ -364,7 +373,7 @@ func vipsExtract(image *C.VipsImage, left, top, width, height int) (*C.VipsImage
|
|||
var buf *C.VipsImage
|
||||
defer C.g_object_unref(C.gpointer(image))
|
||||
|
||||
if width > MAX_SIZE || height > MAX_SIZE {
|
||||
if width > MaxSize || height > MaxSize {
|
||||
return nil, errors.New("Maximum image size exceeded")
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue