I know this looks wrong, but it's there for a reason, and it matches the behavior of the other interpolations. In my tests, the center of a bitmap pixel is at an integral value, meaning that the pixel at (0,0) is a rectangle extending from (-0.5, -0.5) to (0.5, 0.5), and if you enlarge an image you do get out-of-bounds bits on the lower right.
I'm pretty sure I also tested GdipDrawImageRect separately and got the same result.
Vincent Povirk madewokherd@gmail.com wrote:
I know this looks wrong, but it's there for a reason, and it matches the behavior of the other interpolations. In my tests, the center of a bitmap pixel is at an integral value, meaning that the pixel at (0,0) is a rectangle extending from (-0.5, -0.5) to (0.5, 0.5), and if you enlarge an image you do get out-of-bounds bits on the lower right.
I'm pretty sure I also tested GdipDrawImageRect separately and got the same result.
In my tests (which replicate the behaviour of a target application) if an image of say 10x10 pixels is being copied with a magnification world transform then the destination image has right/bottom border completely wrong, and my patch fixes this. Besides, bilinear interpolation does exactly that already - doesn't round pixel positions up, which contradicts your explanation.
In my tests (which replicate the behaviour of a target application) if an image of say 10x10 pixels is being copied with a magnification world transform then the destination image has right/bottom border completely wrong, and my patch fixes this. Besides, bilinear interpolation does exactly that already - doesn't round pixel positions up, which contradicts your explanation.
The same rule about pixel centers applies with bilinear interpolation. That means that at the lower-right corner of a stretched image you end up with places where the lower-right pixel was blended with a pixel from outside the image.
Vincent Povirk madewokherd@gmail.com wrote:
In my tests (which replicate the behaviour of a target application) if an image of say 10x10 pixels is being copied with a magnification world transform then the destination image has right/bottom border completely wrong, and my patch fixes this. Besides, bilinear interpolation does exactly that already - doesn't round pixel positions up, which contradicts your explanation.
The same rule about pixel centers applies with bilinear interpolation. That means that at the lower-right corner of a stretched image you end up with places where the lower-right pixel was blended with a pixel from outside the image.
Just write a test with GdipDrawImageI and scenario described above and you will see the problem. In my case it's even more visible because of indirect magnifaction: image with resolution 100 dpi is being copied to device with 300 dpi.
Just write a test with GdipDrawImageI and scenario described above and you will see the problem. In my case it's even more visible because of indirect magnifaction: image with resolution 100 dpi is being copied to device with 300 dpi.
I just did, and the behavior, though it looks wrong, is the same between builtin and native - the image is shifted by 1/2 pixel so that it's cut off at the upper-left and we have extra transparent space at the lower-right.
Vincent Povirk madewokherd@gmail.com wrote:
Just write a test with GdipDrawImageI and scenario described above and you will see the problem. In my case it's even more visible because of indirect magnifaction: image with resolution 100 dpi is being copied to device with 300 dpi.
I just did, and the behavior, though it looks wrong, is the same between builtin and native - the image is shifted by 1/2 pixel so that it's cut off at the upper-left and we have extra transparent space at the lower-right.
With native gdiplus scenario described earlier works just fine for me, while with built-in there are black borders on bottom/right.
I just did, and the behavior, though it looks wrong, is the same between builtin and native - the image is shifted by 1/2 pixel so that it's cut off at the upper-left and we have extra transparent space at the lower-right.
With native gdiplus scenario described earlier works just fine for me, while with built-in there are black borders on bottom/right.
You should be getting transparent borders on the bottom/right.
This probably means you're using a surface that's not capable of alpha blending, and in that situation gdi_alpha_blend currently draws fully transparent pixels as black when it shouldn't. I'm pretty sure I mentioned that as a problem earlier, around the time you introduced gdi_alpha_blend.
If you compare the size of the image drawn between native/builtin (not counting the border, which native draws as transparent, as does builtin under normal circumstances), I think you'll find that it currently matches and your patch changes it. If you didn't notice, you're probably not enlarging the image enough.
Since GdipDrawImage doesn't accept a source rectangle, and those extra pixels are supposed to be transparent, you could probably have GdipDrawImage subtract 0.5 from your image width and height. That should solve your problem in this limited case without fixing gdi_alpha_blend or introducing a bug.
Vincent Povirk madewokherd@gmail.com wrote:
I just did, and the behavior, though it looks wrong, is the same between builtin and native - the image is shifted by 1/2 pixel so that it's cut off at the upper-left and we have extra transparent space at the lower-right.
With native gdiplus scenario described earlier works just fine for me, while with built-in there are black borders on bottom/right.
You should be getting transparent borders on the bottom/right.
This probably means you're using a surface that's not capable of alpha blending, and in that situation gdi_alpha_blend currently draws fully transparent pixels as black when it shouldn't. I'm pretty sure I mentioned that as a problem earlier, around the time you introduced gdi_alpha_blend.
The problem is not related to a device not supporting alpha blending, I even replaced a TRACE there by ERR just in case, but it never triggers.
If you compare the size of the image drawn between native/builtin (not counting the border, which native draws as transparent, as does builtin under normal circumstances), I think you'll find that it currently matches and your patch changes it. If you didn't notice, you're probably not enlarging the image enough.
I don't see a difference in the image size regardless how much I enlarge the image.
Since GdipDrawImage doesn't accept a source rectangle, and those extra pixels are supposed to be transparent, you could probably have GdipDrawImage subtract 0.5 from your image width and height. That should solve your problem in this limited case without fixing gdi_alpha_blend or introducing a bug.
Subtracting 0.5 from width and height hides the problem, but that's just a compensation to rounding up that my patch is removing.