Skip to content

Commit 11b39f3

Browse files
Add feature to manipulator service to force encode to target extension (#79)
* Add feature to manipulator service to force encode to target extension * Add target image for encoding to different file extension * Update naming from TargetExtension to TargetFormat --------- Co-authored-by: Kenneth Halim <kanisius.halim@gojek.com>
1 parent e276ae0 commit 11b39f3

File tree

5 files changed

+54
-5
lines changed

5 files changed

+54
-5
lines changed
26.3 KB
Loading

pkg/service/manipulator.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ func (m *manipulator) Process(spec processSpec) ([]byte, error) {
6666
if err != nil {
6767
return nil, err
6868
}
69+
if spec.TargetFormat != "" {
70+
f = spec.TargetFormat
71+
}
6972
m.metricService.TrackDuration(decodeDurationKey, t, spec.ImageData)
7073
if params[fit] == crop {
7174
t = time.Now()

pkg/service/manipulator_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,24 @@ func TestManipulator_Process_ReturnsImageAsWebPIfCallerSupportsWebP(t *testing.T
5656
assert.Equal(t, expectedImg, img)
5757
}
5858

59+
// Integration test to verify the flow of encoding with target format
60+
func TestManipulator_Process_ReturnsImageWithTargetFormat(t *testing.T) {
61+
// Use real processor to ensure that right encoder is being used
62+
p := native.NewBildProcessor()
63+
m := NewManipulator(p, nil, metrics.NewPrometheus(prometheus.NewRegistry()))
64+
65+
img, _ := ioutil.ReadFile("../processor/native/_testdata/test.png")
66+
expectedImg, _ := ioutil.ReadFile("../processor/native/_testdata/test_png_to_jpg.jpg")
67+
ext := "jpg"
68+
s := NewSpecBuilder().
69+
WithImageData(img).
70+
WithTargetFormat(ext).
71+
Build()
72+
img, err := m.Process(s)
73+
assert.Nil(t, err)
74+
assert.Equal(t, expectedImg, img)
75+
}
76+
5977
func TestManipulator_Process(t *testing.T) {
6078
mp := &mockProcessor{}
6179
ms := &metrics.MockMetricService{}

pkg/service/spec.go

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,19 @@ type processSpec struct {
1212
ImageData []byte
1313
// Params hold the key-value pairs for the processing job and tells the manipulator what to do with the image
1414
Params map[string]string
15+
// Reformat image to target format
16+
TargetFormat string
1517
// Formats have the information of accepted formats, whether darkroom can return the image using webp or not
1618
formats []string
1719
}
1820

21+
const (
22+
extJPG = "jpg"
23+
extPNG = "png"
24+
extWebP = "webp"
25+
extJPEG = "jpeg"
26+
)
27+
1928
func (ps *processSpec) IsWebPSupported() bool {
2029
for _, f := range ps.formats {
2130
if f == "image/webp" {
@@ -30,6 +39,7 @@ type SpecBuilder interface {
3039
WithImageData(img []byte) SpecBuilder
3140
WithParams(params map[string]string) SpecBuilder
3241
WithFormats(formats []string) SpecBuilder
42+
WithTargetFormat(ext string) SpecBuilder
3343
Build() processSpec
3444
}
3545

@@ -38,6 +48,7 @@ type specBuilder struct {
3848
imageData []byte
3949
params map[string]string
4050
formats []string
51+
extension string
4152
}
4253

4354
func (sb *specBuilder) WithScope(scope string) SpecBuilder {
@@ -60,12 +71,21 @@ func (sb *specBuilder) WithFormats(formats []string) SpecBuilder {
6071
return sb
6172
}
6273

74+
func (sb *specBuilder) WithTargetFormat(ext string) SpecBuilder {
75+
switch ext {
76+
case extJPG, extJPEG, extPNG, extWebP:
77+
sb.extension = ext
78+
}
79+
return sb
80+
}
81+
6382
func (sb *specBuilder) Build() processSpec {
6483
return processSpec{
65-
Scope: sb.scope,
66-
ImageData: sb.imageData,
67-
Params: sb.params,
68-
formats: sb.formats,
84+
Scope: sb.scope,
85+
ImageData: sb.imageData,
86+
Params: sb.params,
87+
formats: sb.formats,
88+
TargetFormat: sb.extension,
6989
}
7090
}
7191

pkg/service/spec_test.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,20 @@ func TestSpecBuilder_Build(t *testing.T) {
1111
img := []byte("imageData")
1212
params := map[string]string{"foo": "bar"}
1313
formats := []string{"image/webp", "image/apng"}
14-
14+
ext := "png"
1515
spec := NewSpecBuilder().
1616
WithScope(scope).
1717
WithImageData(img).
1818
WithParams(params).
1919
WithFormats(formats).
20+
WithTargetFormat(ext).
2021
Build()
2122

2223
assert.Equal(t, spec.Scope, scope)
2324
assert.Equal(t, spec.ImageData, img)
2425
assert.Equal(t, spec.Params, params)
2526
assert.Equal(t, spec.formats, formats)
27+
assert.Equal(t, spec.TargetFormat, ext)
2628
}
2729

2830
func TestSpec_IsWebPSupported(t *testing.T) {
@@ -34,3 +36,9 @@ func TestSpec_IsWebPSupported(t *testing.T) {
3436
spec = NewSpecBuilder().WithFormats(f).Build()
3537
assert.False(t, spec.IsWebPSupported())
3638
}
39+
40+
func TestSpec_Build_TargetExtensionNotValid(t *testing.T) {
41+
ext := "gif"
42+
spec := NewSpecBuilder().WithTargetFormat(ext).Build()
43+
assert.Empty(t, spec.TargetFormat)
44+
}

0 commit comments

Comments
 (0)