diff --git a/README.md b/README.md index c601a7f..7101b4e 100644 --- a/README.md +++ b/README.md @@ -260,6 +260,21 @@ Invert image colors. } ``` +#### Blur + +Blur image using Gaussian functions. + +**Step definition**: + +```json +{ + "type": 6, + "options": { + "sigma": 50.0 + } +} +``` + ## Authors - [Fabian Vowie](https://gogs.informatik.hs-fulda.de/FabianVowie) diff --git a/pipelines/executable_step.go b/pipelines/executable_step.go index 3909ad4..c20c8c0 100644 --- a/pipelines/executable_step.go +++ b/pipelines/executable_step.go @@ -100,3 +100,17 @@ func (s InvertImageStep) Execute(src image.Image) (image.Image, error) { src = imaging.Invert(src) return src, nil } + +// Blur image + +type BlurImageStep struct { + Step + Options struct { + Sigma float64 `json:"sigma"` + } `json:"options"` +} + +func (s BlurImageStep) Execute(src image.Image) (image.Image, error) { + src = imaging.Blur(src, s.Options.Sigma) + return src, nil +} diff --git a/pipelines/pipeline_test.go b/pipelines/pipeline_test.go index 1c1ec00..d2d6857 100644 --- a/pipelines/pipeline_test.go +++ b/pipelines/pipeline_test.go @@ -409,6 +409,52 @@ func TestExecuteSteps(t *testing.T) { os.Remove(storageProvider.GetPath(Bucket, dest)) }) + t.Run("Image blur step is successful", func(t *testing.T) { + const Bucket string = "pipeline_test_10" + const Payload string = `{ + "name": "example pipeline", + "type": 1, + "removeMetadata": false, + "steps": [ + { + "name": "blur", + "type": 6, + "options": { + "sigma": 50.0 + } + } + ] + }` + + wd, _ := os.Getwd() + pipe := DeserializePipelines([][]byte{[]byte(Payload)})[0] + + storageProvider := storage.GetFileSystemStorageProvider("test", "..") + + // copy test file to storage bucket + _, err := storageProvider.StoreExisting(Bucket, "source.jpg", filepath.Join(wd, "../tests/files/900x900.jpg")) + assert.Nil(t, err, "Test file should be readable") + assert.FileExists(t, storageProvider.GetPath(Bucket, "source.jpg")) + + // run pipeline steps + dest, err := pipe.Run("source.jpg", Bucket, storageProvider) + assert.Nil(t, err) + assert.FileExists(t, storageProvider.GetPath(Bucket, dest)) + + // read image config + file, err := storageProvider.OpenFile(Bucket, dest) + assert.Nil(t, err) + + imgConf, _, err := image.DecodeConfig(file) + assert.Nil(t, err) + + assert.Equal(t, 900, imgConf.Width) + assert.Equal(t, 900, imgConf.Height) + + // clean up + os.Remove(storageProvider.GetPath(Bucket, "source.jpg")) + os.Remove(storageProvider.GetPath(Bucket, dest)) + }) } // output options diff --git a/pipelines/step.go b/pipelines/step.go index 90919b3..f6d18d5 100644 --- a/pipelines/step.go +++ b/pipelines/step.go @@ -14,6 +14,7 @@ const ( TypeGrayscaleImageStep TypeFitImageStep TypeInvertImageStep + TypeBlurImageStep ) type Step struct { @@ -58,6 +59,13 @@ func (s Step) GetExecutable() (IExecutableStep, error) { case TypeGrayscaleImageStep: return GrayscaleImageStep{}, nil + + case TypeBlurImageStep: + step := BlurImageStep{} + if err := json.Unmarshal(s.Options, &step.Options); err != nil { + return nil, err + } + return step, nil } return nil, errors.New("invalid type")