귀하의 이미지 복사본 코드에는 복사 된 특정 이미지에 맞지 않는 가정으로 인해 몇 가지 오류가 있습니다.
Bitmap resImg = new Bitmap(foreImg.Width, foreImg.Height);
대신해야한다 : 당신이 복사 작업을위한 새로운 목표 이미지를 만들 때하지 않습니다 때로는 진정한 있지만, 많은 경우에 어떻게 될 것인가 소스 이미지와 정확히 같은 픽셀 표현을해야합니다 첫 번째 가정 우리를 : 또는 이미지에 따라 잘못 설정하지 않을 수도 있습니다
Bitmap resImg = new Bitmap(foreImg.Width, foreImg.Height, foreImg.PixelFormat);
다음 가정은 원본 이미지 PixelFormat
의 크기가 정확히 3 바이트임을 암시 가정하고 PixelFormat.Format24bppRgb
형식에 해당 (또는 Pixel 구조의 Red, Green 또는 Blue 채널의 크기가 무엇인지 알 수 없으므로 3 바이트의 배수가되며 PixelFormat.Format48bppRgb
형식 일 수 있습니다) 따라서 바이트는 원본 이미지에서이 위치에 따라 대상 이미지로 복사됩니다 인수.
정확하게 복사하려면 원본 이미지에서 대상 이미지로 정확히 같은 바이트 수를 복사해야하며 기본 Pixel
구조를 사용할 필요가 없으며 대신 정수 복사본을 기반으로 할 수 있습니다. 마지막으로 목표는 대신 가장 빠른 방법은 전문 메모리 복사 기능을 사용하여 픽셀에 의해 내용 픽셀입니다있어 분석의 이미지를 복사하는 경우 : 다음은 코드가있는 복사합니다 코드가 나열되어
System.Buffer.MemoryCopy((void*)oneBits.Scan0, (void*)thrBits.Scan0, byteLength, byteLength);
을 이미지는 ulong
을 carrier
으로 사용합니다. Pixel
크기를 바이트로 반환하는 함수를 추가했습니다.이 함수는 바이트 단위로 이미지 크기를 계산하고 정확한 복사를 수행하는 데 사용됩니다. 그러나 이미지 데이터를 분석하는 데 사용할 수있는 것보다 일치하는 Pixel
구조를 선택하는 데 사용할 수 있습니다. 예를 들어, 이미지가 PixelFormat.Format24bppRgb
인 경우 Pixel
구조를 3 바이트 크기 및 RGB 색상으로 사용할 수 있습니다. 다른 형식의 경우 이미지 Pixel
형식을 직접 복제하는 다른 Pixel
구조를 정의해야합니다.
using System;
using System.Drawing;
using System.Drawing.Imaging;
namespace DrawingImagingOperations
{
class Program
{
static void Main(string[] args)
{
Bitmap foreImg = new Bitmap(@"..\..\YaHI9.jpg");
//output image
Bitmap resImg = new Bitmap(foreImg.Width, foreImg.Height, foreImg.PixelFormat);
unsafe
{
BitmapData oneBits = foreImg.LockBits(new Rectangle(0, 0, foreImg.Width, foreImg.Height), ImageLockMode.ReadOnly, foreImg.PixelFormat);
BitmapData thrBits = resImg.LockBits(new Rectangle(0, 0, resImg.Width, resImg.Height), ImageLockMode.WriteOnly, resImg.PixelFormat);
int pixelSize = GetPixelSize(foreImg.PixelFormat);
var byteLength = foreImg.Width * foreImg.Height * pixelSize;
var length = byteLength/sizeof(UInt64);
var reminder = byteLength % sizeof(UInt64);
System.Threading.Tasks.Parallel.For(0, length, j =>
{
ulong* pxOne = (ulong*)((byte*)oneBits.Scan0 + j * sizeof(UInt64));
ulong* pxRes = (ulong*)((byte*)thrBits.Scan0 + j * sizeof(UInt64));
*pxRes = *pxOne;
});
if (reminder > 0)
{
byte* pSrc = (byte*)oneBits.Scan0 + (pixelSize * length);
byte* pDst = (byte*)thrBits.Scan0 + (pixelSize * length);
for (int j = length; j < byteLength; j++)
*pDst++ = *pSrc++;
}
foreImg.UnlockBits(oneBits);
resImg.UnlockBits(thrBits);
}
resImg.Save(@"..\..\imgCopy.jpg");
}
internal static int GetPixelSize(PixelFormat data)
{
switch (data)
{
case PixelFormat.Format8bppIndexed:
return 1;
case PixelFormat.Format16bppGrayScale:
case PixelFormat.Format16bppRgb555:
case PixelFormat.Format16bppRgb565:
case PixelFormat.Format16bppArgb1555:
return 2;
case PixelFormat.Format24bppRgb:
return 3;
case PixelFormat.Canonical:
case PixelFormat.Format32bppArgb:
case PixelFormat.Format32bppPArgb:
case PixelFormat.Format32bppRgb:
return 4;
case PixelFormat.Format48bppRgb:
return 6;
case PixelFormat.Format64bppArgb:
case PixelFormat.Format64bppPArgb:
return 8;
}
throw new FormatException("Unsupported image format: " + data);
}
}
}
최대 이미지 처리 유형을 설명해 주시겠습니까? –
'픽셀'이란 무엇입니까? – harold
Pixel 구조체에 알파 바이트가 없습니다. – Adrian