libgdiplus icon indicating copy to clipboard operation
libgdiplus copied to clipboard

ImageInterpolationMode not working with GdipDrawImageRectRect

Open jhergens opened this issue 4 years ago • 1 comments

Setting Graphics.ImageInterpolationMode has no effect.

The following code:

var target = new Bitmap(100, 100);
using (var g = Graphics.FromImage(target))
{
    g.Clear(Color.Red);
    g.PixelOffsetMode = PixelOffsetMode.Half;            
    g.InterpolationMode = InterpolationMode.NearestNeighbor;

    var bmp = new Bitmap(2, 2);
    bmp.SetPixel(0, 0, Color.Black);
    bmp.SetPixel(0, 1, Color.White);
    bmp.SetPixel(1, 0, Color.White);
    bmp.SetPixel(1, 1, Color.Black);

    var destRect = new RectangleF(20, 20, 60, 60);
    var srcRect = new RectangleF(0, 0, 2, 2);

    g.DrawImage(bmp, destRect, srcRect, GraphicsUnit.Pixel);
}

Renders like this: checkers

It is expect to render like this: checkers_expected

We are building libgdiplus from main.

The problem seems to be at the end of GdipDrawImageRectRect. It creates two surfaces, and sets an interpolation for the first of them. I can't see that that surface is used for anything. Seems to be dead code? For the second surface no interpolation filter is set. The commented out line fixes the issue:

gdip_bitmap_ensure_surface (preprocessed_image);

filter = cairo_pattern_create_for_surface (preprocessed_image->surface);
cairo_pattern_set_filter (filter, gdip_get_cairo_filter (graphics->interpolation));

cairo_matrix_translate (&mat, srcx, srcy);

if (!gdip_near_zero(srcwidth - dstwidth) || !gdip_near_zero(srcheight - dstheight))
    cairo_matrix_scale (&mat, srcwidth / dstwidth, srcheight / dstheight);

cairo_matrix_translate (&mat, -dstx, -dsty);

pattern = cairo_pattern_create_for_surface (preprocessed_image->surface);
// cairo_pattern_set_filter (pattern, gdip_get_cairo_filter (graphics->interpolation));
cairo_pattern_set_matrix (pattern, &mat);

jhergens avatar Dec 06 '21 19:12 jhergens

Experiencing the same issue.

TalicZealot avatar Oct 18 '23 20:10 TalicZealot