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

Fix gaussian blurring changing the blur colour when transperancy is used #1834

Merged
merged 2 commits into from
Nov 18, 2021

Conversation

Turnerj
Copy link
Contributor

@Turnerj Turnerj commented Nov 17, 2021

Prerequisites

  • I have written a descriptive pull-request title
  • I have verified that there are no overlapping pull-requests open
  • I have verified that I am following the existing coding patterns and practice as demonstrated in the repository. These follow strict Stylecop rules 👮.
  • I have provided test coverage for my change (where applicable)

Description

Firstly, all credit goes to @JimBobSquarePants for identifying the fix.

Blurring an image that has a transparent background can lead to strange results depending on the colour.
For example, take this code:

using var image = new Image<Rgba32>(400, 400);
image.Mutate(x => x.Fill(Color.ParseHex("48f25b"), new Rectangle(100, 100, 200, 200)).GaussianBlur(20));

Master generates this:

image

This PR generates:

image

I do want to add tests for it, just working out how to do it like how you have your Bokeh blur tests.

@codecov
Copy link

codecov bot commented Nov 17, 2021

Codecov Report

Merging #1834 (088e92c) into master (31e6230) will decrease coverage by 0%.
The diff coverage is 100%.

Impacted file tree graph

@@           Coverage Diff           @@
##           master   #1834    +/-   ##
=======================================
- Coverage      87%     87%    -1%     
=======================================
  Files         937     937            
  Lines       48420   48421     +1     
  Branches     6054    6054            
=======================================
- Hits        42323   42222   -101     
- Misses       5095    5193    +98     
- Partials     1002    1006     +4     
Flag Coverage Δ
unittests 87% <100%> (-1%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
...s/Convolution/Convolution2PassProcessor{TPixel}.cs 61% <100%> (+<1%) ⬆️
...ageSharp/Formats/Webp/Lossless/PredictorEncoder.cs 87% <0%> (-11%) ⬇️
.../ImageSharp/Formats/Webp/Lossless/LosslessUtils.cs 89% <0%> (-9%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 59903aa...088e92c. Read the comment docs.

@Turnerj
Copy link
Contributor Author

Turnerj commented Nov 17, 2021

Took a little while but I worked out how to do the reference images for tests (and yep, I did run the optimizer on them so the file size is smaller for the repo).

This is the source image:
blur

Running the test on master:
OnFullImage_Rgba32_blur_3
InBox_Rgba32_blur_5

Running the test on this PR:

OnFullImage_Rgba32_blur_3

InBox_Rgba32_blur_5

As you can see, the blurring was doing all sorts of weirdness with colours without that line.

@Turnerj Turnerj marked this pull request as ready for review November 17, 2021 14:40
@JimBobSquarePants JimBobSquarePants added this to the 2.0.0 milestone Nov 18, 2021
Copy link
Member

@JimBobSquarePants JimBobSquarePants left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HighFiveTopGunGIF

@JimBobSquarePants JimBobSquarePants merged commit 9777a3b into SixLabors:master Nov 18, 2021
@Turnerj Turnerj deleted the gaussian-blur-fix branch November 18, 2021 12:01
@@ -396,6 +396,8 @@ private void Convolve4(int y, Span<Vector4> span)

PixelOperations<TPixel>.Instance.ToVector4(this.configuration, sourceRow, sourceBuffer);

Numerics.Premultiply(sourceBuffer);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be made conditional on PixelTypeInfo.AlphaRepresentation:

PixelAlphaRepresentation? alphaRepresentation = PixelOperations<TPixel>.Instance.GetPixelTypeInfo()?.AlphaRepresentation;
// Premultiply only if alpha representation is unknown or Unassociated:
bool needsPremultiplication = alphaRepresentation == null || alphaRepresentation.Value == PixelAlphaRepresentation.Unassociated;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. Something to look into. I keep meaning to see what else we can add to PixelTypeInfo actually that would help us in other places.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants