여기에서 읽은 것처럼 memcpy를 사용하여 24bpp 이미지를 자르려고합니다 : cropping an area from BitmapData with C#. 문제는 내 sourceImage가 32bpp 일 때만 작동한다는 것입니다. 내 sourceImage가 24bpp 일 때 이미지가 손상됩니다. 내가 변화하고있어 유일한 것은이 sourceImage PixelFormat이 아닌 CropBitmap 방법의 코드 중 하나이기 때문에memcpy를 사용한 이미지 자르기가 24bpp 이미지에서 실패합니다.
class Program
{
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
static unsafe extern int memcpy(byte* dest, byte* src, long count);
static void Main(string[] args)
{
var image = new Bitmap(@"C:\Users\Vincent\Desktop\CroppedScaledBitmaps\adsadas.png");
//Creates a 32bpp image - Will work eventhough I treat it as a 24bpp image in the CropBitmap method...
//Bitmap newBitmap = new Bitmap(image);
//Creates a 24bpp image - Will produce a corrupt cropped bitmap
Bitmap newBitmap = (Bitmap)image.Clone();
var croppedBitmap = CropBitmap(newBitmap, new Rectangle(0, 0, 150, 150));
croppedBitmap.Save(@"C:\Users\Vincent\Desktop\CroppedScaledBitmaps\PieceOfShit.png", ImageFormat.Png);
Console.ReadLine();
}
static public Bitmap CropBitmap(Bitmap sourceImage, Rectangle rectangle)
{
Console.WriteLine("Bits per pixel of sourceImage: {0}", Image.GetPixelFormatSize(sourceImage.PixelFormat));
var sourceBitmapdata = sourceImage.LockBits(rectangle, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
var croppedImage = new Bitmap(rectangle.Width, rectangle.Height, PixelFormat.Format24bppRgb);
var croppedBitmapData = croppedImage.LockBits(new Rectangle(0, 0, rectangle.Width, rectangle.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
unsafe
{
byte* sourceImagePointer = (byte*)sourceBitmapdata.Scan0.ToPointer();
byte* croppedImagePointer = (byte*)croppedBitmapData.Scan0.ToPointer();
memcpy(croppedImagePointer, sourceImagePointer, croppedBitmapData.Stride * rectangle.Height);
}
sourceImage.UnlockBits(sourceBitmapdata);
croppedImage.UnlockBits(croppedBitmapData);
return croppedImage;
}
}
나는 매우 혼란 스러워요. 그래서 나는 항상 32bpp sourceImage 경우에도 24bpp Pixelformat 사용하여 LockBits 호출합니다.
복사하는 바이트 수를 계산하는 여러 가지 방법을 시도했지만 결과적으로 모두 동일한 손상된 이미지가 나타납니다.
도움을 주시면 감사하겠습니다.
당신은 코드를 디버깅하고 값을 확인 했습니까? 'Stride' 값은 음수 일 수 있습니다. 비트 맵은 거꾸로 메모리에 저장됩니다. – Guffa
32bpp sourceImage 또는 24bpp sourceImage를 사용할 경우 보폭이 동일합니다. (이것은 비트를 잠그면 32bpp sourceImage를 24bpp 이미지로 처리하기 때문일 것입니다.) – VincentC
'memcpy'를 사용할 필요가 없으며 대신'Marshal' 클래스를 사용하십시오. 더 안전합니다. – Dai