지난번 포스팅에서 Bitmap.Clone과 new Bitmap의 차이를 보여드리며
이미지 복사하는 방법에 대해 알아봤습니다.
이번 포스팅은 Bitmap을 사용하면서
이미지를 복사하는 다른 방법인 Marshal.Copy() 메서드에 대해 작성하였습니다.
| Marshal.Copy() 개요
- Marshal.Copy 메서드란 Bitmap 이미지를 관리되는
메모리와 비관리 메모리 간에 복사해야 할 때가 있습니다.
이러한 작업을 효율적으로 수행하기 위해
System.Runtime.InteropServices.Marshal 클래스의 Copy 메서드입니다.
기본 형식)
public static void Copy(IntPtr source, byte[] destination, int startIndex, int length);
- source : 복사할 데이터의 시작 위치를 가리키는 포인터로 IntPtr 형식
- destination : 복사된 데이터를 저장할 바이트 배열
- startIndex : 복사를 시작할 destination 배열의 인덱스
- length : 복사할 데이터의 길이
| Bitmap 이미지 관리와 비관리 메모리 복사
- Marshal.Copy()에 대해 공부하는 중 알게 된 "비관리 메모리"에 대해 잠시 알아보고 넘어가겠습니다.
비관리 메모리(Unmanaged Memory)
- .NET 프레임워크의 가비지 컬렉션과 메모리 관리 시스템에 의해 관리되지 않는 메모리 영역입니다. .NET 런타임 밖에서 할당되고 해제되며, 프로그래머가 명시적으로 메모리를 할당하고 해제해야 하며 비관리 메모리를 사용할 때 주의해야 할 중요한 점은 메모리 할당 및 해제를 명시적으로 처리해야 하며, 이를 잘못 관리할 경우 메모리 누수나 프로그램 충돌을 초래할 수 있습니다.
아래 예시를 통해 Bitmap 클래스를 사용하여 로드한 이미지 데이터를 관리되는 메모리에서 비관리 메모리로 복사하고 다시 복사한 데이터를 사용하는 방법에 대해 알아보겠습니다.
예시)
// Bitmap 이미지 로드
Bitmap sourceBitmap = new Bitmap("example.jpg");
// 이미지 데이터를 비관리 메모리로 복사
Rectangle rect = new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height);
BitmapData bmpData = sourceBitmap.LockBits(rect, ImageLockMode.ReadOnly, sourceBitmap.PixelFormat);
IntPtr sourcePtr = bmpData.Scan0;
int bufferSize = bmpData.Stride * sourceBitmap.Height;
byte[] destinationArray = new byte[bufferSize];
Marshal.Copy(sourcePtr, destinationArray, 0, bufferSize);
sourceBitmap.UnlockBits(bmpData);
// destinationArray를 가지고 작업 수행
// ...
// 메모리 해제
sourceBitmap.Dispose();
- 이 예시에서, LockBits 메서드를 사용하여 Bitmap 데이터를 잠금 상태로 가져오고, Marshal.Copy를 사용하여 비관리 메모리로 데이터를 복사합니다. 그런 다음 UnlockBits를 사용하여 이미지 데이터를 해제하고, 비관리 메모리의 데이터를 사용하여 원하는 작업을 수행할 수 있습니다.
| 마치며
- Marshal.Copy 메서드를 사용하면 Bitmap 이미지 데이터를 관리되는 메모리와 비관리 메모리 간에 효율적으로 복사할 수 있습니다. 이를 통해 이미지 처리 작업을 보다 효율적으로 수행할 수 있으며, Bitmap 데이터를 다른 비관리 코드와 상호 작용할 때 유용하게 사용할 수 있습니다. 코드에서 메모리 관리에 주의하여 메모리 누수를 방지하는 것이 중요하다는 것을 알게 되었습니다.
질문이 있으시거나 틀린 점이 있으면 댓글로 남겨주세요
다음 포스팅으로 찾아오겠습니다.
감사합니다 :)
'C#' 카테고리의 다른 글
자동 구현 속성 이해 (Auto-implemented Properties) (0) | 2023.10.30 |
---|---|
[C#] CancellationToken 이해 (0) | 2023.10.25 |
[C#] Bitmap.Clone() vs new Bitmap() 비교 (0) | 2023.09.26 |
[C#] Bitmap.LockBits 메서드 (0) | 2023.09.25 |
[C#] unsafe / fixed 키워드 (0) | 2023.09.25 |