1

This code basically takes an image and crops it according to a detected image (in this case, it detects a decentralized fingerprint, and returns a new Bitmap with the fingerprint centered and cropped).

It turns out that, depending on the image, each resulting Bitmap will have a different size (for example, my test is returning a 425x448 Bitmap, since the identified image has that size), when in fact I need the image to return with a specific size (512x512).

I've already tried to change all the height and width variables of the code, but none satisfy this desired condition. Either it creates a Bitmap with the size of 512x512 and stretches the original image (violating the original ratio), or it creates a 512x512 Bitmap with the cropped image but with a black border on the right and bottom sides.

Any hints of what can be changed or included in the code?

Edit: More clearly, I need to create a 512x512 canvas for the 425x448 image without changing the size or dimensions of the image (it should be 425x448 inside a 512x512 canvas).

        private byte[] GetAndCropImage(byte[] image, IEnumerable<YoloItem> yoloItems)
        {
            byte[] imageRet = null;

            var topYoloItem = yoloItems?.Where(x => x.Confidence >= 0.30).OrderByDescending(x => x.Confidence).First();

            MemoryStream ms = new MemoryStream(image);
            Bitmap src = new Bitmap(ms);
            Rectangle cropRect = new Rectangle(topYoloItem.X, topYoloItem.Y, topYoloItem.Width, topYoloItem.Height);
            Bitmap target = new Bitmap(cropRect.Width, cropRect.Height);
            using (Graphics g = Graphics.FromImage(target))
            {
                g.DrawImage(src, new Rectangle(0, 0, target.Width, target.Height),
                                 cropRect,
                                 GraphicsUnit.Pixel);
            }

            target.SetResolution(512, 512);

            ImageConverter converter = new ImageConverter();
            imageRet = (byte[])converter.ConvertTo(target, typeof(byte[]));

            return imageRet;
        }
  • If you need to set the Resolution, which is the Dpi descriptor of an Image, not the *size*, you set it before drawing on it. Possibly, to match the source Image Dpi. See, e.g, [Image is not drawn at the correct spot](https://stackoverflow.com/a/51456467/7444103) -- Do you want to center a smaller image on a 512x512 canvas? Or scale it to fit these bounds without *stretching* it? You'll have a *border* in any case when the cropped image size (scaled or not) doesn't match the destination Bitmap's size. – Jimi Feb 28 '22 at 18:34
  • Also, you always need to copy the original Image to an ARGB32 Bitmap. See, e.g., [Resizing a Bitmap used as watermark the result shows dark borders](https://stackoverflow.com/a/61977870/7444103) – Jimi Feb 28 '22 at 18:39
  • I would like to center a smaller image on a 512x512 canvas, avoiding resizing and stretching the image. One of my options would be to create a new bitmap with the dimensions 512x512, and paste the image in it; or even, add pad on the image to the desired size. But these two options seem not very correct in my opinion. – Matheus Reis Feb 28 '22 at 18:42
  • 2
    Well, the code you find in my second comment has a method named `CenterRectangleOnRectangle()`. It also shows how to scale a Bitmap to fit specific bounds without distorting it. -- Another similar method is described here: [Disable Image blending on a PictureBox](https://stackoverflow.com/a/54726707/7444103) – Jimi Feb 28 '22 at 18:45
  • Not like centering is _hard_... take the intended dimension, subtract the actual dimension, and divide by 2, and you got the offset to paint at. – Nyerguds Mar 09 '22 at 12:47

0 Answers0