문제

Delphi 7에는 TCanvas 구성 요소를 사용하여 일부 정보를 출력하는 라이브러리가 있습니다.결과 이미지는 약 4800*6000픽셀 정도인데 인쇄해서 다른 이름으로 저장하고 싶습니다. .jpeg.

이를 달성하기 위해 TBitmap을 생성하고 Canvas를 라이브러리에 매개변수로 제공한 다음 비트맵을 jpeg에 할당했습니다.비트맵의 너비와 높이를 설정하려고 할 때 "이 명령을 처리하는 데 사용할 수 있는 저장 공간이 부족합니다."라는 예외가 발생하기 때문에 이는 너무 많은 메모리를 사용하고 있는 것 같습니다.

// output to printer
Printer.BeginDoc();
doPrint(Printer.Canvas);
Printer.EndDoc();

// output in bmp.Canvas
bmp := TBitmap.Create;
bmp.Width := Printer.PageWidth;
bmp.Height := Printer.PageHeight; // <- BAM! Exception!
doPrint(bmp.Canvas);

// save as jpeg
jpg := TJPEGImage.Create;
jpg.Assign(bmp);
jpg.SaveToFile('...');

// free
bmp.Free();
jpg.Free();

내가 도대체 ​​뭘 잘못하고있는 겁니까?Printer.Canvas를 다음과 같이 직접 저장할 수 있습니까? .jpeg 파일?

편집하다:대략적인 이미지 크기를 2000*2000에서 4800*6000으로 업데이트했습니다.

도움이 되었습니까?

해결책

Graphic32의 TBitmap32를 사용하여 큰 비트맵을 처리할 수 있어야 합니다(http://www.graphics32.org/wiki/)

다른 팁

Ben Ziegler가 제안한 것처럼 bmp의 크기를 조정하기 전에 bmp의 픽셀 형식을 설정해야 합니다.이것이 모든 차이를 만듭니다.

이 오류는 비트맵 크기를 데스크탑 크기보다 크게 설정한 경우 발생합니다.이 오류를 방지하려면 다음 방법으로 장치 독립적 비트맵을 생성할 수 있습니다.

bmp := TBitmap.Create;
bmp.HandleType := bmDIB;
bmp.Width := Printer.PageWidth;
bmp.Height := Printer.PageHeight; 

이 솔루션이 필요한지 여부는 비디오 카드의 기능에 따라 다릅니다.한 세션에 할당된 비디오 RAM이 많지 않은 터미널 서버 상황에서 이 오류가 많이 발생했습니다.이 솔루션을 사용하면 Delphi가 비디오 카드의 메모리 대신 비트맵에 일반 RAM을 사용하도록 강제할 수 있습니다.

Delphi의 TBitmap 클래스는 이렇게 큰 비트맵을 처리하는 데 문제가 있습니다.아니요, TCanvas를 .jpg 파일에 직접 저장할 수 없습니다.

내 컴퓨터(Windows XP, Delphi 2006)에서 다음 코드를 시도했지만 예외가 발생하지 않았습니다.어떤 OS를 사용하고 있나요?

  procedure TForm3.Button3Click(Sender: TObject);
  var
     bmp : TBitmap;
  begin
     bmp := TBitmap.Create;
     bmp.PixelFormat := pf32bit;
     bmp.Width := 6000;
     bmp.Height := 4800;
     bmp.Free;
  end;

mghie가 말했듯이:그것은 당신의 시스템을 참조하십시오 대형 비트맵의 EFG 컴퓨터 실습실

PixelFormat을 pf32bit 또는 pf24bit(예: Ben Ziegler의 예)로 설정해 보십시오. 대부분의 경우 이 PixelFormat이 트릭을 수행합니다(제 기억으로는 주로 XP에서 이루어졌습니다).더 많은 정보를 확인하실 수 있습니다 여기.

JPEG 형식이 아닙니다.사양에서는 최대 32767x32767 픽셀의 비트맵을 허용합니다.

문제는 큰 비트맵의 막대한 메모리 소비입니다. 그리고 궁극적으로 Windows 플랫폼까지 추적할 수 있는 TCanvas 제한입니다.

내 NativeJpg 라이브러리는 시각화와 별도로 JPEG 처리를 디코딩합니다.결과적으로 더 관리하기 쉬운 비트맵 타일을 사용하여 "스트립 바이 스트립"을 사용하여 이러한 JPEG를 저장합니다.

NativeJpg는 오픈 소스이며 여기에서 이 lib를 다운로드할 수 있습니다.http://www.simdesign.nl/forum/viewforum.php?f=16

거대한 인공 JPEG 이미지를 만들고 저장하는 방법을 보려면 타일 데모를 보십시오.

감사합니다, 닐스

메모리를 덜 소비하려면 언제든지 더 작은 비트맵을 만들어 볼 수 있습니다.프린터 높이를 10으로 나누거나 최대 높이를 1000으로 설정한다고 가정해 보겠습니다.단지 제안일 뿐이며 귀하의 경우에 적용 가능한지 확실하지 않습니다.페이지당 하나 이상의 이미지가 생성됩니다.

이것이 효과가 있을지, 도움이 될지 확실하지 않습니다.하지만 우리는 구성 요소를 JPEG로 저장하는 함수를 만들었습니다.

    function SaveComponentToJPeg(mControl: TWinControl): TJpegImage;
    var
      bmp: TPicture;
      jpg : TJpegImage;
      dc: HDC;
      wnd: HWND;
      Params: array[0..255] of Char;

    begin
      bmp:=TPicture.Create;
      jpg := TJpegImage.create;
      try
        bmp.Bitmap.Width  := mControl.Width  - 05;  // Deduct for border.
        bmp.Bitmap.Height := mControl.Height -05;  // Deduct for border.
        wnd               := mControl.Handle;  //ctiveWindow;
        dc                := GetDc(wnd);
        BitBlt(bmp.Bitmap.Canvas.Handle,0,0,bmp.Width,bmp.Height,dc,0,0,SrcCopy);
        ReleaseDc(wnd, dc);
        jpg.assign(bmp.bitmap);
        result := jpg
      finally
        bmp.Free;
      end;
    end;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top