Skip to content
Snippets Groups Projects
Commit 88f75fe8 authored by ensiouel's avatar ensiouel
Browse files

добавлен пакет для работы с изображениями

parent 003ed41e
No related branches found
No related tags found
No related merge requests found
package imgconv
import (
"image"
"image/gif"
"image/jpeg"
"image/png"
"io"
"golang.org/x/image/bmp"
"golang.org/x/image/tiff"
)
const (
JPEG = "jpeg"
PNG = "png"
GIF = "gif"
TIFF = "tiff"
BMP = "bmp"
)
func init() {
RegisterFormatEncoder(JPEG, func(w io.Writer, img image.Image) error { return jpeg.Encode(w, img, nil) })
RegisterFormatEncoder(PNG, func(w io.Writer, img image.Image) error { return png.Encode(w, img) })
RegisterFormatEncoder(GIF, func(w io.Writer, img image.Image) error { return gif.Encode(w, img, nil) })
RegisterFormatEncoder(TIFF, func(w io.Writer, img image.Image) error { return tiff.Encode(w, img, nil) })
RegisterFormatEncoder(BMP, func(w io.Writer, img image.Image) error { return bmp.Encode(w, img) })
}
package imgconv
import (
"image"
"io"
"os"
"strings"
"git.perx.ru/perxis/perxis-go/pkg/errors"
)
var builtinFormats = map[string]string{
"jpg": "jpeg",
"tif": "tiff",
}
var defaultFormatEncoderRegistry = make(map[string]EncodeFunc)
type EncodeFunc func(w io.Writer, img image.Image) error
func RegisterFormatEncoder(format string, fn EncodeFunc) {
defaultFormatEncoderRegistry[format] = fn
}
func Encode(w io.Writer, format string, img image.Image) error {
encoder, ok := defaultFormatEncoderRegistry[format]
if !ok {
return errors.Errorf("unknown format: %s", format)
}
err := encoder(w, img)
if err != nil {
return errors.Wrap(err, "encode image")
}
return nil
}
func Decode(r io.Reader) (image.Image, string, error) {
img, ext, err := image.Decode(r)
if err != nil {
return nil, "", errors.Wrap(err, "decode image")
}
return img, ext, nil
}
func Open(filename string) (image.Image, string, error) {
file, err := os.Open(filename)
if err != nil {
return nil, "", errors.Wrap(err, "open file")
}
defer file.Close()
img, ext, err := Decode(file)
if err != nil {
return nil, "", errors.Wrap(err, "decode file")
}
return img, ext, nil
}
func NormalizeFormat(format string) string {
format = strings.ToLower(format)
format = strings.TrimPrefix(format, ".")
if v, ok := builtinFormats[format]; ok {
return v
}
return format
}
package imgconv
import (
"bytes"
"image"
"os"
"testing"
"github.com/stretchr/testify/require"
)
func TestOpen(t *testing.T) {
_, ext, err := Open("testdata/1.jpeg")
if err != nil {
return
}
require.NoError(t, err)
require.Equal(t, JPEG, ext)
}
func TestNormalizeFormat(t *testing.T) {
require.Equal(t, NormalizeFormat("jpg"), JPEG)
require.Equal(t, NormalizeFormat("png"), PNG)
require.Equal(t, NormalizeFormat("tif"), TIFF)
require.Equal(t, NormalizeFormat("any"), "any")
require.Equal(t, NormalizeFormat(".jpg"), JPEG)
require.Equal(t, NormalizeFormat(".gif"), GIF)
require.Equal(t, NormalizeFormat(".bmp"), BMP)
require.Equal(t, NormalizeFormat(".any"), "any")
}
func TestEncode(t *testing.T) {
var tests = []struct {
name string
input string
wantErr bool
}{
{
name: "unknown format",
input: "go",
wantErr: true,
},
{
name: "jpeg format",
input: JPEG,
wantErr: false,
},
{
name: "png format",
input: PNG,
wantErr: false,
},
{
name: "gif format",
input: GIF,
wantErr: false,
},
{
name: "tiff format",
input: TIFF,
wantErr: false,
},
{
name: "bmp format",
input: BMP,
wantErr: false,
},
}
img := image.NewRGBA(image.Rect(0, 0, 10, 10))
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
buf := new(bytes.Buffer)
err := Encode(buf, tt.input, img)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}
func TestDecode(t *testing.T) {
var tests = []struct {
name string
input string
output string
wantErr bool
}{
{
name: "unknown format",
input: "testdata/1.go",
wantErr: true,
},
{
name: "jpeg format",
input: "testdata/1.jpeg",
output: JPEG,
wantErr: false,
},
{
name: "png format",
input: "testdata/1.png",
output: PNG,
wantErr: false,
},
{
name: "gif format",
input: "testdata/1.gif",
output: GIF,
wantErr: false,
},
{
name: "tiff format",
input: "testdata/1.tiff",
output: TIFF,
wantErr: false,
},
{
name: "bmp format",
input: "testdata/1.bmp",
output: BMP,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
file, err := os.Open(tt.input)
if err != nil {
t.Fatal(err)
}
defer file.Close()
_, ext, err := Decode(file)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
require.Equal(t, tt.output, ext)
}
})
}
}
pkg/images/imgconv/testdata/1.bmp

313 KiB

pkg/images/imgconv/testdata/1.gif

289 KiB

package testdata
// hi
pkg/images/imgconv/testdata/1.jpeg

43.8 KiB

pkg/images/imgconv/testdata/1.png

8.2 KiB

pkg/images/imgconv/testdata/1.tiff

14.6 KiB

pkg/images/imgconv/testdata/1.webp

29.6 KiB

//go:build webp
package imgconv
import (
"image"
"io"
"github.com/bep/gowebp/libwebp"
"github.com/bep/gowebp/libwebp/webpoptions"
// Нужно включать в сборку для вызова регистрации декодера в стандартном
// пакете "images" для декодирования файлов webp.
_ "golang.org/x/image/webp"
)
const (
WEBP = "webp"
)
func init() {
RegisterFormatEncoder(WEBP, func(w io.Writer, img image.Image) error { return libwebp.Encode(w, img, webpoptions.EncodingOptions{}) })
}
//go:build webp
package imgconv
import (
"bytes"
"image"
"os"
"testing"
"github.com/stretchr/testify/require"
)
func TestEncodeWebP(t *testing.T) {
img := image.NewRGBA(image.Rect(0, 0, 10, 10))
buf := new(bytes.Buffer)
err := Encode(buf, WEBP, img)
require.NoError(t, err)
}
func TestDecodeWebP(t *testing.T) {
file, err := os.Open("testdata/1.webp")
if err != nil {
t.Fatal(err)
}
defer file.Close()
_, ext, err := Decode(file)
require.NoError(t, err)
require.Equal(t, WEBP, ext)
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment