Browse Source

Move jpeg quality setting from pipeline step to new output options

feature/add-image-processing
Roman Zipp 3 years ago
parent
commit
4e920243ae
  1. 11
      config/example.json
  2. 13
      pipelines/executable_step.go
  3. 25
      pipelines/executable_step_test.go
  4. 13
      pipelines/pipeline.go
  5. 42
      pipelines/pipeline_test.go
  6. 8
      pipelines/step.go

11
config/example.json

@ -12,13 +12,10 @@
"height": 720, "height": 720,
"upscale": false "upscale": false
} }
},
{
"name": "compress image",
"type": 1,
"options": {
"quality": 80
} }
],
"output": {
"format": 0,
"quality": 90
} }
]
} }

13
pipelines/executable_step.go

@ -24,16 +24,3 @@ func (s ResizeImageStep) Execute(src image.Image) (image.Image, error) {
src = imaging.Resize(src, s.Options.Width, s.Options.Height, imaging.Linear) src = imaging.Resize(src, s.Options.Width, s.Options.Height, imaging.Linear)
return src, nil return src, nil
} }
// Compress image
type CompressImageStep struct {
Step
Options struct {
Quality int `json:"quality"`
} `json:"options"`
}
func (s CompressImageStep) Execute(src image.Image) (image.Image, error) {
return src, nil
}

25
pipelines/executable_step_test.go

@ -32,31 +32,6 @@ func TestDeserializeOptionsResizeImage(t *testing.T) {
}) })
} }
func TestDeserializeOptionsCompressImage(t *testing.T) {
const Payload string = `{
"name": "example pipeline",
"type": 0,
"removeMetadata": false,
"steps": [
{
"name": "compress image",
"type": 1,
"options": {
"quality": 80
}
}
]
}`
t.Run("Image pipeline deserialization is successful", func(t *testing.T) {
values := DeserializePipelines([][]byte{[]byte(Payload)})
_, err := values[0].GetSteps()[0].GetExecutable()
assert.Equal(t, nil, err)
})
}
func TestDeserializeMissingOptions(t *testing.T) { func TestDeserializeMissingOptions(t *testing.T) {
const Payload string = `{ const Payload string = `{
"name": "example pipeline", "name": "example pipeline",

13
pipelines/pipeline.go

@ -36,6 +36,10 @@ type Pipeline struct {
Type PipelineType `json:"type" faker:"-"` Type PipelineType `json:"type" faker:"-"`
RemoveMetadata bool `json:"remove_metadata" faker:"-"` RemoveMetadata bool `json:"remove_metadata" faker:"-"`
Steps []Step `json:"steps" faker:"-"` Steps []Step `json:"steps" faker:"-"`
Output struct {
Format int `json:"format"`
Quality int `json:"quality"`
} `json:"output" faker:"-"`
} }
func (p Pipeline) Run(srcPath, bucketName string, storageProvider storage.IStorageProvider) (string, error) { func (p Pipeline) Run(srcPath, bucketName string, storageProvider storage.IStorageProvider) (string, error) {
@ -58,9 +62,16 @@ func (p Pipeline) Run(srcPath, bucketName string, storageProvider storage.IStora
} }
} }
format := imaging.Format(p.Output.Format)
var options []imaging.EncodeOption
if p.Output.Quality != 0 {
options = append(options, imaging.JPEGQuality(p.Output.Quality))
}
// encode image to io buffer // encode image to io buffer
buffer := new(bytes.Buffer) buffer := new(bytes.Buffer)
if err := imaging.Encode(buffer, src, imaging.JPEG); err != nil {
if err := imaging.Encode(buffer, src, format, options...); err != nil {
return "", err return "", err
} }

42
pipelines/pipeline_test.go

@ -99,3 +99,45 @@ func TestResizeImage(t *testing.T) {
os.Remove(storageProvider.GetPath(Bucket, dest)) os.Remove(storageProvider.GetPath(Bucket, dest))
}) })
} }
func TestEncodeImageWithJpegQuality(t *testing.T) {
const Payload string = `{
"name": "example pipeline",
"type": 1,
"removeMetadata": false,
"steps": [
{
"name": "resize image",
"type": 0,
"options": {
"width": 1280,
"height": 720,
"upscale": false
}
}
],
"output": {
"quality": 50
}
}`
const Bucket string = "pipeline_test_02"
t.Run("Image resizing is successful", func(t *testing.T) {
wd, _ := os.Getwd()
pipe := DeserializePipelines([][]byte{[]byte(Payload)})[0]
storageProvider := storage.GetFileSystemStorageProvider("test", "..")
_, 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"))
dest, err := pipe.Run("source.jpg", Bucket, storageProvider)
assert.Nil(t, err)
assert.FileExists(t, storageProvider.GetPath(Bucket, dest))
// clean up
os.Remove(storageProvider.GetPath(Bucket, "source.jpg"))
os.Remove(storageProvider.GetPath(Bucket, dest))
})
}

8
pipelines/step.go

@ -9,7 +9,6 @@ type StepType int
const ( const (
TypeResizeImageStep StepType = iota TypeResizeImageStep StepType = iota
TypeCompressImageStep
) )
type Step struct { type Step struct {
@ -26,13 +25,6 @@ func (s Step) GetExecutable() (IExecutableStep, error) {
return nil, err return nil, err
} }
return step, nil return step, nil
case TypeCompressImageStep:
step := CompressImageStep{}
if err := json.Unmarshal(s.Options, &step.Options); err != nil {
return nil, err
}
return step, nil
} }
return nil, errors.New("invalid type") return nil, errors.New("invalid type")

Loading…
Cancel
Save