52 lines
1.8 KiB
C#
52 lines
1.8 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using System.Drawing.Imaging;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace ClassLibrary
|
|
{
|
|
public unsafe sealed class FastImageCroper : IDisposable
|
|
{
|
|
private readonly Bitmap _srcImg;
|
|
private readonly BitmapData _srcImgBitmapData;
|
|
private readonly int _bpp;
|
|
private readonly byte* _srtPrt;
|
|
|
|
public FastImageCroper(Bitmap srcImg)
|
|
{
|
|
_srcImg = srcImg;
|
|
_srcImgBitmapData = srcImg.LockBits(new Rectangle(0, 0, srcImg.Width, srcImg.Height), ImageLockMode.ReadOnly, srcImg.PixelFormat);
|
|
_bpp = _srcImgBitmapData.Stride / _srcImgBitmapData.Width; // == 4
|
|
_srtPrt = (byte*)_srcImgBitmapData.Scan0.ToPointer();
|
|
}
|
|
|
|
public Bitmap Crop(Rectangle rectangle)
|
|
{
|
|
Bitmap dstImg = new Bitmap(rectangle.Width, rectangle.Height, _srcImg.PixelFormat);
|
|
BitmapData dstImgBitmapData = dstImg.LockBits(new Rectangle(0, 0, dstImg.Width, dstImg.Height), ImageLockMode.WriteOnly, dstImg.PixelFormat);
|
|
byte* dstPrt = (byte*)dstImgBitmapData.Scan0.ToPointer();
|
|
byte* srcPrt = _srtPrt + rectangle.Y * _srcImgBitmapData.Stride + rectangle.X * _bpp;
|
|
|
|
for (int y = 0; y < rectangle.Height; y++)
|
|
{
|
|
int srcIndex = y * _srcImgBitmapData.Stride;
|
|
int croppedIndex = y * dstImgBitmapData.Stride;
|
|
memcpy(dstPrt + croppedIndex, srcPrt + srcIndex, dstImgBitmapData.Stride);
|
|
}
|
|
|
|
dstImg.UnlockBits(dstImgBitmapData);
|
|
return dstImg;
|
|
}
|
|
|
|
|
|
public void Dispose()
|
|
{
|
|
_srcImg.UnlockBits(_srcImgBitmapData);
|
|
}
|
|
|
|
|
|
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
|
|
private static extern int memcpy(byte* dest, byte* src, long count);
|
|
}
|
|
}
|