작은 워터 마크 프로그램을 작성하여 이미지에 사용자 지정 워터 마크를 추가했습니다. 흰색과 검은 색 두 개의 워터 마크가 있습니다. 워터 마크는 항상 이미지의 왼쪽 아래에 배치됩니다. 이미지의 해당 영역을 복제하여 해당 위치 (밝은 영역에서는 검은 색 워터 마크, 어두운 영역에서는 흰색 워터 마크)를 기반으로 어떤 워터 마크를 배치해야하는지 결정합니다.비트 맵 클론에서 WinForms 메모리 부족 예외
내 컴퓨터에서 응용 프로그램 (디버그 또는 일반)을 사용할 때 - 아무런 문제가 없습니다. 모든 이미지가 처리되고 올바른 위치에 워터 마크가 추가됩니다.
그러나 클라이언트 컴퓨터에서는 프로그램이 복제 부분에 OutOfMemory 예외를 발생시키는 모든 이미지에서 중단됩니다.
OutOfMemory Exception은 경계를 벗어난 영역을 지정할 때도 throw됩니다.하지만이 함수는 내 컴퓨터에서 매력처럼 작동하므로이 경우를 상상할 수 없습니다. 게다가, 몇 번 시도해도 프로그램이 중단되지 않습니다. 복제하려는 모든 시도가 중단됩니다.
텍스트 (DrawString 메서드)가 있는지 여부는 중요하지 않습니다. 클론에서 깨진다.
처리되는 이미지는 크지 만 "거대한"(최대 6016 x 4000 픽셀)은 아니지만 더 작은 이미지 (3264 x 2448 픽셀)로도 클라이언트가 중단됩니다.
변수 :
bmOriginal
: 원래 비트 맵
processImage
- : 워터 마크 아래 추가 정보 입력란
black
원 화상 (의 PictureBox) bmOriginal
이
watermarkText
의 비트 맵 카피 및 white
: 워터 마크 이미지가 포함 된 그림 상자
watermarkCombo
: 자동 흰색 또는 검은 색 선택 콤보 박스 (자동 실패)
코드 : 이제 using (Bitmap watermarkClone = bmOriginal.Clone(watermarkArea, bmOriginal.PixelFormat))
큰 질문 : 내가 없애 어떻게 오류의
using (Graphics gWatermark = Graphics.FromImage(bmOriginal))
{
gWatermark.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
System.Drawing.SolidBrush drawBrush = new System.Drawing.SolidBrush(System.Drawing.Color.Black);
// position watermark - watermark should be 10% of the image height
int watermarkHeight = (int)(processImage.Image.Height * 0.1);
int watermarkPadding = (int)(watermarkHeight * 0.1); // not completely true, but asume watermark is square
Rectangle watermarkArea = new Rectangle(watermarkPadding, processImage.Image.Height - (watermarkPadding + (watermarkText.Text.Length == 0 ? 0 : watermarkPadding) + watermarkHeight), watermarkHeight, watermarkHeight);
// determine color watermark
bmWatermark = (Bitmap)black.Image;
if (watermarkCombo.SelectedIndex == 0)
{
using (Bitmap watermarkClone = bmOriginal.Clone(watermarkArea, bmOriginal.PixelFormat))
{
var pixels = Pixels(watermarkClone);
if (pixels.Average((Func<Color, decimal>)Intensity) < 110) // human eye adoption; normal threshold should be 128
{
bmWatermark = (Bitmap)white.Image;
drawBrush = new System.Drawing.SolidBrush(System.Drawing.Color.White);
}
}
}
else if (watermarkCombo.SelectedIndex == 1)
{
bmWatermark = (Bitmap)white.Image;
drawBrush = new System.Drawing.SolidBrush(System.Drawing.Color.White);
}
// draw the watermark
gWatermark.DrawImage(bmWatermark, watermarkArea.X, watermarkArea.Y, watermarkArea.Width, watermarkArea.Height);
// draw the text (if needed)
if (watermarkText.Text.Length > 0)
{
System.Drawing.Font drawFont = new System.Drawing.Font("Tahoma", (float)watermarkPadding);
gWatermark.DrawString(watermarkText.Text, drawFont, drawBrush, watermarkPadding, bmOriginal.Height - (watermarkPadding * 2));
}
}
bmOriginal.Save(System.IO.Path.Combine(diWatermarked.FullName, fileName), System.Drawing.Imaging.ImageFormat.Jpeg);
라인 그 OutOfMemory 예외 .. 누구의 아이디어?
편집 내가 자동으로 워터 마크의 색상을 결정하고 바로 워터 마크를 추가하지 않도록 선택 일반적으로 프로그램 기능 (의는 흰색 하나를 가정 해 봅시다). 오류 로그에서 스택 추적을 보았습니다 (예외를 출력하고 모든 내부 예외가있는 함수를 포착 함).
범위를 벗어난 영역을 지정할 때 복제 기능을 사용하는 많은 OOM 예외가 발생한다는 것을 알고 있습니다. 하지만 여기서는 그렇지 않습니다.
디버그 모드에서 응용 프로그램을 사용할 때이 내 메모리에서 볼 때, 나는 5.36 기가 프로그램에서 시작 시작하고 내가 언급 실행을 실행할 때 (5.42 기가의 최대 스파이크) 정규화 5.39 (GB)는 그렇지 않아 미친 듯이 추측하는 기억.
내가 사용하는 코드는 평균 "색상"을 결정합니다 (StackOverflow에있는 사람의 것입니다 - 다른 일부 대답에서 복사했으나 링크를 찾을 수 없음).
// functions used to determine watermark color
private static decimal ComponentAverage(decimal a, decimal b)
{
return Math.Min(a, b) + Math.Abs(a - b)/2M;
}
private static decimal Intensity(Color color)
{
decimal result = color.A;
result = ComponentAverage(result, color.R);
result = ComponentAverage(result, color.G);
result = ComponentAverage(result, color.B);
return result;
}
private static IEnumerable<Color> Pixels(Bitmap bitmap)
{
for (int x = 0; x < bitmap.Width; x++)
for (int y = 0; y < bitmap.Height; y++)
yield return bitmap.GetPixel(x, y);
}
SOURCE 여기에 테스트 프로젝트가있다 : http://hotpepper.nu/oomtestapp.zip
으로 나누어되지 않았기 때문에 마지막 타일 오류 것 응용 프로그램은 런타임에 필요를 충족시키기에 충분한 메모리를 할당 할 수 없으므로 경계 확인과는 분명히 다르지 않습니다. –
일반적으로 개체를 처리하지 않으면 GDI를 사용하여이 작업을 쉽게 실행할 수 있습니다. 다른 이미지에 대한 참조가 많고 코드에없는 내용이있을 수 있습니다. 그 이유는 간단합니다. – MichaC
코드는 테스트 할 수 없으며 문제를 재현 할 수 없습니다. – MichaC