Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add blur #189

Merged
merged 3 commits into from
Mar 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ Parameters to call the picfit service are:

.. code-block:: html

<img src="http://localhost:3001/{method}?url={url}&path={path}&w={width}&h={height}&upscale={upscale}&sig={sig}&op={operation}&fmt={format}&q={quality}&deg={degree}&pos={position}"
<img src="http://localhost:3001/{method}?url={url}&path={path}&w={width}&h={height}&upscale={upscale}&sig={sig}&op={operation}&fmt={format}&q={quality}&deg={degree}&pos={position}&filter={filter}"

- **path** - The filepath to load the image using your source storage
- **operation** - The operation to perform, see Operations_
Expand All @@ -390,6 +390,7 @@ Parameters to call the picfit service are:
- **quality** - The quality to save the image, by default the quality will be the highest possible, it will be only applied on ``JPEG`` format
- **degree** - The degree (``90``, ``180``, ``270``) to rotate the image
- **position** - The position to flip the image
- **filter** - The filter for the effect operation (``blur``)

To use this service, include the service url as replacement
for your images, for example:
Expand Down Expand Up @@ -491,6 +492,16 @@ Flat can be used only with the [multiple operation system].

In order to understand the Flat operation, please read the following `docs <https://github.com/thoas/picfit/blob/superpose-images/docs/flat.md>`_.

Effect
------

Add effect to the given image.

- **filter** - The desired effect : ``blur``

You have to pass the ``effect`` value to the ``op`` parameter
to use this operation.

Methods
=======

Expand Down
6 changes: 6 additions & 0 deletions constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ var StickPositions = []string{
TopRight,
}

const FilterBlur = "blur"

var Filters = []string{
FilterBlur,
}

const ModifiedTimeFormat = time.RFC1123

const RequestIDCtx = "request-id"
4 changes: 3 additions & 1 deletion engine/backend/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"context"
"fmt"

"github.com/disintegration/imaging"
"github.com/go-spectest/imaging"
"github.com/pkg/errors"
"github.com/thoas/picfit/image"
)
Expand All @@ -16,6 +16,7 @@ var MethodNotImplementedError = errors.New("Not implemented")
type Options struct {
Color string
Degree int
Filter string
Format imaging.Format
Height int
Images []image.ImageFile
Expand All @@ -33,6 +34,7 @@ func (o Options) String() string {

// Engine is an interface to define an image engine
type Backend interface {
Effect(ctx context.Context, img *image.ImageFile, options *Options) ([]byte, error)
Fit(ctx context.Context, img *image.ImageFile, options *Options) ([]byte, error)
Flat(ctx context.Context, background *image.ImageFile, options *Options) ([]byte, error)
Flip(ctx context.Context, img *image.ImageFile, options *Options) ([]byte, error)
Expand Down
2 changes: 1 addition & 1 deletion engine/backend/exif.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"image"
"io"

"github.com/disintegration/imaging"
"github.com/go-spectest/imaging"
"github.com/rwcarlsen/goexif/exif"
_ "golang.org/x/image/webp"
)
Expand Down
5 changes: 5 additions & 0 deletions engine/backend/gifsicle.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ func (b *Gifsicle) Fit(ctx context.Context, img *image.ImageFile, options *Optio
return nil, MethodNotImplementedError
}

// Effect implements Backend.
func (b *Gifsicle) Effect(ctx context.Context, img *image.ImageFile, options *Options) ([]byte, error) {
return nil, MethodNotImplementedError
}

// Flat implements Backend.
func (b *Gifsicle) Flat(ctx context.Context, img *image.ImageFile, options *Options) ([]byte, error) {
return nil, MethodNotImplementedError
Expand Down
21 changes: 20 additions & 1 deletion engine/backend/goimage.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"bytes"
"context"
"fmt"
"github.com/thoas/go-funk"
"github.com/thoas/picfit/constants"
"image"
"image/color/palette"
"image/draw"
Expand All @@ -13,7 +15,7 @@ import (
"io"
"math"

"github.com/disintegration/imaging"
"github.com/go-spectest/imaging"

imagefile "github.com/thoas/picfit/image"

Expand Down Expand Up @@ -102,6 +104,23 @@ func (e *GoImage) Fit(ctx context.Context, img *imagefile.ImageFile, options *Op
return e.transform(image, options, imaging.Fit)
}

func (e *GoImage) Effect(ctx context.Context, img *imagefile.ImageFile, options *Options) ([]byte, error) {
image, err := e.source(img)
if err != nil {
return nil, err
}
width, height := imageSize(image)
size := funk.MaxInt([]int{width, height})
sigma := size / 20

switch options.Filter {
case constants.FilterBlur:
return e.toBytes(imaging.Blur(image, float64(sigma)), options.Format, options.Quality)
}

return nil, MethodNotImplementedError
}

func (e *GoImage) toBytes(img image.Image, format imaging.Format, quality int) ([]byte, error) {
var buf bytes.Buffer

Expand Down
2 changes: 1 addition & 1 deletion engine/backend/goimage_flat.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"strconv"
"strings"

"github.com/disintegration/imaging"
"github.com/go-spectest/imaging"
colorful "github.com/lucasb-eyer/go-colorful"

"github.com/thoas/picfit/constants"
Expand Down
7 changes: 5 additions & 2 deletions engine/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package engine
import (
"context"
"fmt"
"github.com/pkg/errors"
"github.com/thoas/picfit/engine/backend"
"github.com/thoas/picfit/engine/config"
"github.com/thoas/picfit/image"
Expand Down Expand Up @@ -124,7 +125,7 @@ func (e Engine) Transform(ctx context.Context, output *image.ImageFile, operatio
output.Source = processed
break
}
if err != backend.MethodNotImplementedError {
if !errors.Is(err, backend.MethodNotImplementedError) {
return nil, err
}
}
Expand Down Expand Up @@ -152,7 +153,9 @@ func operate(ctx context.Context, b backend.Backend, img *image.ImageFile, opera
return b.Fit(ctx, img, options)
case Flat:
return b.Flat(ctx, img, options)
case Effect:
return b.Effect(ctx, img, options)
default:
return nil, fmt.Errorf("Operation not found for %s", operation)
return nil, fmt.Errorf("operation not found for %s", operation)
}
}
2 changes: 2 additions & 0 deletions engine/operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ func (o Operation) String() string {
}

const (
Effect = Operation("effect")
Fit = Operation("fit")
Flat = Operation("flat")
Flip = Operation("flip")
Expand All @@ -19,6 +20,7 @@ const (
)

var Operations = map[string]Operation{
Effect.String(): Effect,
Fit.String(): Fit,
Flat.String(): Flat,
Flip.String(): Flip,
Expand Down
7 changes: 4 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ require (
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/cstockton/go-conv v0.0.0-20170524002450-66a2b2ba36e1
github.com/davecgh/go-spew v1.1.1
github.com/disintegration/imaging v1.6.2
github.com/getsentry/sentry-go v0.19.0
github.com/gin-gonic/contrib v0.0.0-20201101042839-6a891bf89f19
github.com/gin-gonic/gin v1.9.1
github.com/go-playground/validator/v10 v10.15.4 // indirect
github.com/go-spectest/imaging v1.0.6
github.com/k0kubun/pp v3.0.1+incompatible
github.com/lucasb-eyer/go-colorful v0.0.0-20180709185858-c7842319cf3a
github.com/mattn/go-isatty v0.0.19 // indirect
Expand All @@ -25,16 +25,17 @@ require (
github.com/ulule/gokvstores v0.1.1-0.20221229151109-3bd12fb72ebe
github.com/ulule/gostorages v0.2.5-0.20230920134537-c63293fd790c
github.com/urfave/cli v1.22.10
golang.org/x/image v0.10.0
golang.org/x/image v0.13.0
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0 // indirect
gopkg.in/fukata/golang-stats-api-handler.v1 v1.0.0
)

require (
github.com/go-spectest/imaging v1.0.6
github.com/google/uuid v1.3.0
github.com/prometheus/client_golang v1.14.0
golang.org/x/sync v0.1.0
golang.org/x/sync v0.4.0
)

require (
Expand Down
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ github.com/go-playground/validator/v10 v10.15.4 h1:zMXza4EpOdooxPel5xDqXEdXG5r+W
github.com/go-playground/validator/v10 v10.15.4/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
github.com/go-spectest/imaging v1.0.6 h1:b7qzcXLs1p9uZMjAKO+oe+a6EGo5JbwPDkcWafmTnX8=
github.com/go-spectest/imaging v1.0.6/go.mod h1:/AyhBt5HEFGDPy2AxP+hcV5NH8QQpftJP9g3yGOVtvs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
Expand Down Expand Up @@ -507,6 +509,8 @@ golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+o
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.10.0 h1:gXjUUtwtx5yOE0VKWq1CH4IJAClq4UGgUA3i+rpON9M=
golang.org/x/image v0.10.0/go.mod h1:jtrku+n79PfroUbvDdeUWMAI+heR786BofxrbiSF+J0=
golang.org/x/image v0.13.0 h1:3cge/F/QTkNLauhf2QoE9zp+7sr+ZcL4HnoZmdwg9sg=
golang.org/x/image v0.13.0/go.mod h1:6mmbMOeV28HuMTgA6OSRkdXKYw/t5W9Uwn2Yv1r3Yxk=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
Expand Down Expand Up @@ -610,6 +614,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
Expand Down
34 changes: 17 additions & 17 deletions parameters.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ package picfit
import (
"context"
"fmt"
"slices"
"strconv"
"strings"

"github.com/disintegration/imaging"
"github.com/go-spectest/imaging"
"github.com/pkg/errors"
"github.com/ulule/gostorages"

Expand Down Expand Up @@ -197,17 +198,10 @@ func (p Processor) newBackendOptionsFromParameters(operation engine.Operation, q
return nil, fmt.Errorf("Parameter \"pos\" not found in query string")
}

stick, _ := qs["stick"].(string)
if stick != "" {
var exists bool
for i := range constants.StickPositions {
if stick == constants.StickPositions[i] {
exists = true
break
}
}
if !exists {
return nil, fmt.Errorf("Parameter \"stick\" has wrong value. Available values are: %v", constants.StickPositions)
stick, ok := qs["stick"].(string)
if ok {
if !slices.Contains(constants.StickPositions, stick) {
return nil, fmt.Errorf("parameter \"stick\" has wrong value. Available values are: %v", constants.StickPositions)
}
}

Expand Down Expand Up @@ -241,14 +235,20 @@ func (p Processor) newBackendOptionsFromParameters(operation engine.Operation, q
}
}

filter, ok := qs["filter"].(string)
if ok && !slices.Contains(constants.Filters, filter) {
return nil, fmt.Errorf("parameter \"filter\" has wrong value. Available values are: %v", constants.Filters)
}

return &backend.Options{
Width: width,
Color: color,
Degree: degree,
Filter: filter,
Height: height,
Upscale: upscale,
Position: position,
Stick: stick,
Quality: quality,
Degree: degree,
Color: color,
Stick: stick,
Upscale: upscale,
Width: width,
}, nil
}
2 changes: 1 addition & 1 deletion processor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (

"github.com/cstockton/go-conv"

"github.com/disintegration/imaging"
"github.com/go-spectest/imaging"

"github.com/stretchr/testify/assert"

Expand Down
Loading