Skip to content

Commit

Permalink
Add Transform ICC Profile API (#208)
Browse files Browse the repository at this point in the history
* Add TransformICCProfile method

* Add tests for transform ICC profile method

* Fix transform ICC case for images without ICC profile
  • Loading branch information
AttilaTheFun authored Dec 30, 2021
1 parent 6433b63 commit ef478ad
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 0 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions vips/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -1133,6 +1133,24 @@ func (r *ImageRef) RemoveICCProfile() error {
return nil
}

// TransformICCProfile transforms from the embedded ICC profile of the image to the icc profile at the given path.
func (r *ImageRef) TransformICCProfile(outputProfilePath string) error {

// If the image has an embedded profile, that will be used and the input profile ignored.
// Otherwise, images without an input profile are assumed to use a standard RGB profile.
embedded := r.HasICCProfile()
inputProfile := SRGBIEC6196621ICCProfilePath

out, err := vipsICCTransform(r.image, outputProfilePath, inputProfile, IntentPerceptual, 0, embedded)
if err != nil {
govipsLog("govips", LogLevelError, fmt.Sprintf("failed to do icc transform: %v", err.Error()))
return err
}

r.setImage(out)
return nil
}

// OptimizeICCProfile optimizes the ICC color profile of the image.
// For two color channel images, it sets a grayscale profile.
// For color images, it sets a CMYK or non-CMYK profile based on the image metadata.
Expand Down
22 changes: 22 additions & 0 deletions vips/image_golden_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,28 @@ func TestImage_EmbedBackground_NoAlpha(t *testing.T) {
}, nil)
}

func TestImage_TransformICCProfile_RGB_No_Profile(t *testing.T) {
goldenTest(t, resources+"jpg-24bit.jpg",
func(img *ImageRef) error {
return img.TransformICCProfile(SRGBIEC6196621ICCProfilePath)
},
func(result *ImageRef) {
assert.True(t, result.HasICCProfile())
assert.Equal(t, InterpretationSRGB, result.Interpretation())
}, nil)
}

func TestImage_TransformICCProfile_RGB_Embedded(t *testing.T) {
goldenTest(t, resources+"jpg-24bit-icc-adobe-rgb.jpg",
func(img *ImageRef) error {
return img.TransformICCProfile(SRGBIEC6196621ICCProfilePath)
},
func(result *ImageRef) {
assert.True(t, result.HasICCProfile())
assert.Equal(t, InterpretationSRGB, result.Interpretation())
}, nil)
}

func TestImage_OptimizeICCProfile_CMYK(t *testing.T) {
goldenTest(t, resources+"jpg-32bit-cmyk-icc-swop.jpg",
func(img *ImageRef) error {
Expand Down
16 changes: 16 additions & 0 deletions vips/image_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,22 @@ func TestImageRef_RemoveICCProfile(t *testing.T) {
assert.True(t, image.HasIPTC())
}

func TestImageRef_TransformICCProfile(t *testing.T) {
Startup(nil)

image, err := NewImageFromFile(resources + "jpg-24bit-icc-adobe-rgb.jpg")
require.NoError(t, err)

require.True(t, image.HasIPTC())
require.True(t, image.HasICCProfile())

err = image.TransformICCProfile(SRGBIEC6196621ICCProfilePath)
require.NoError(t, err)

assert.True(t, image.HasIPTC())
assert.True(t, image.HasICCProfile())
}

func TestImageRef_Close(t *testing.T) {
Startup(nil)

Expand Down

0 comments on commit ef478ad

Please sign in to comment.