Crop more then source picture actually have

Dec 16, 2010 at 12:39 PM

Hi

I have an improvement to suggest that Crop only copy from the source if that is available.

Check code below:
public static WriteableBitmap Crop(this WriteableBitmap bmp, int x, int y, int width, int height) { WriteableBitmap result = new WriteableBitmap(width, height); int srcWidth = bmp.PixelWidth; for (int line = 0; line < height && line + y < bmp.PixelHeight; line++) { var srcOff = ((y + line) * srcWidth + x) * SizeOfArgb; var dstOff = line * width * SizeOfArgb; int length; if (width + x > bmp.PixelWidth) length = (bmp.PixelWidth - x) * SizeOfArgb; else length = width * SizeOfArgb; Buffer.BlockCopy(bmp.Pixels, srcOff, result.Pixels, dstOff, length); } return result; }

Coordinator
Dec 16, 2010 at 3:27 PM

Hi Markus,

You mean there's no boundary check being performed. Good catch. I left this out originally to get the best performance, since each branching takes some time.

Should be a quick fix and I will look into this right now.

 

- Rene Schulte 

Coordinator
Dec 16, 2010 at 3:46 PM

OK, I just checked r65378 in. See http://writeablebitmapex.codeplex.com/SourceControl/changeset/changes/65378

I implemented the boundary check before the loop to avoid unnecessary branches, which cost performance. I also added checks for x and y.

      public static WriteableBitmap Crop(this WriteableBitmap bmp, int x, int y, int width, int height)
      {
         var srcWidth = bmp.PixelWidth;
         var srcHeight = bmp.PixelHeight;

         // If the rectangle is completly out of the bitmap
         if(x > srcWidth || y > srcHeight)
         {
            return new WriteableBitmap(0, 0);
         }

         // Clamp to boundaries
         if (x < 0) x = 0;
         if (x + width >= srcWidth) width = (srcWidth - 1) - x;
         if (y < 0) y = 0;
         if (y + height >= srcHeight) height = (srcHeight - 1) - y;

         // Copy the pixels line by line using fast BlockCopy
         var result = new WriteableBitmap(width, height);
         for (var line = 0; line < height; line++)
         {
            var srcOff = ((y + line) * srcWidth + x) * SizeOfArgb;
            var dstOff = line * width * SizeOfArgb;
            Buffer.BlockCopy(bmp.Pixels, srcOff, result.Pixels, dstOff, width * SizeOfArgb);
         }
         return result;
      }

- Rene