Repository navigation
[FEAT]: Better Feathering #2
Copy link
Copy link
Closed
Labels
enhancementNew feature or requestNew feature or request
Description
Hi Steven! Thanks for this project, it really helped me see behind the curtain.
I was getting some unfavourable halos around some of my low res tests. I ended up making more use of the semi-transparency provided by the model on the pixels that transition between foreground to background. Perhaps this can help someone else.
`public async Task RemoveBackgroundAsync(Stream StreamImage, Stream MaskStream)
{
StreamImage.Position = 0;
MaskStream.Position = 0;
var ImageWithBg = await Image.LoadAsync<Rgba32>(StreamImage);
var MaskImage = await Image.LoadAsync<Rgba32>(MaskStream);
using var ImageWithBgRemoved = new Image<Rgba32>(ImageWithBg.Width, ImageWithBg.Height);
// Define your cutoff range.
// Values below MinVal become 0 alpha (transparent).
// Values above MaxVal become 255 alpha (opaque).
// Anything in between is scaled linearly.
const byte MinVal = 70;
const byte MaxVal = 117;
byte AdjustAlpha(byte MaskValue)
{
if (MaskValue <= MinVal)
return 0;
if (MaskValue >= MaxVal)
return 255;
float Proportion = (MaskValue - MinVal) / (float)(MaxVal - MinVal);
return (byte)(Proportion * 255f);
}
// Walk over every pixel, using the mask’s R channel.
WalkImage(ImageWithBg.Height, ImageWithBg.Width, (x, y) =>
{
var SourcePixel = ImageWithBg[x, y];
var MaskPixel = MaskImage[x, y];
// Compute a new alpha value using the linear mapping.
byte NewAlpha = AdjustAlpha(MaskPixel.R);
// Construct the new pixel with the same RGB, but replaced alpha.
ImageWithBgRemoved[x, y] = new Rgba32(SourcePixel.R, SourcePixel.G, SourcePixel.B, NewAlpha);
});
var Result = new MemoryStream();
await ImageWithBgRemoved.SaveAsync(Result, new PngEncoder());
Result.Position = 0;
return Result;
}`
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request
Activity
StevanFreeborn commentedon Mar 2, 2025
@julianadormon thank you for sharing!
Definitely agree the edge between the foreground and background is rough.
I'll experiment with this and see about adding to app like a configurable range passed as options.
[-]Slightly better feathering.[/-][+][FEAT]: Better Feathering[/+]StevanFreeborn commentedon Jul 15, 2026
Apologies it took me so long to get back to this feedback. I've been stubbing my toe on it over the last year or so while making thumbnails for my YouTube videos. I think the changes I introduced in #3 will help with this issue. Here is an example of the results on an image I think that demonstrates the issue.
Test image:
Previous version:
New version: