Avatar billede lanstorp Nybegynder
03. august 2002 - 12:42 Der er 10 kommentarer og
1 løsning

Save to bitmap

Gemmer et panel med en opengl scene til en bitmap eller en jpeg. Det funker fint. Nu har jeg så brugt en MessageDlg til at spørge om brugeren vil overskrive billedet, hvis det findes i forvejen. Problemet er så, at der kommer et sort område, der hvor MessageDlg var på skærmen, på mit bitmap. Det hjælper ikke at gentegne hverken panel eller form. Nogen forslag, koden ser sådan ud:
procedure SavePanelGLSceneToBitmap;
var
  Bitmap :  TBitmap;
  sFileName : string;
  Extension:  STRING;
  JPEG    :  TJPEGImage;
begin
  if FormMain.SavePictureDialog.Execute then begin
    //sFileName := ExtractFilePath(Application.ExeName) + XPROGRAM;
    if FileExists(FormMain.SavePictureDialog.FileName) then begin
      if MessageDlg('Overwrite existing file ?', mtConfirmation, [mbYes, mbNo], 0) = mrNo then
      Exit;
    end;

    Extension := UpperCase(ExtractFileExt(FormMain.SavePictureDialog.FileName));
    if Extension = '.JPG' then begin
      Bitmap := TBitmap.Create;
      JPEG := TJPEGImage.Create;
      JPEG.CompressionQuality := 80;  // fairly low since artifact don't matter
      try
        Bitmap.Width  := FormMain.PanelGLScene.Width;
        Bitmap.Height := FormMain.PanelGLScene.Height;
        // Copy the Panel area from the Form into a separate Bitmap
        Bitmap.Canvas.CopyRect(Rect(0,0, Bitmap.Width,Bitmap.Height),
                    FormMain.Canvas,
                    Rect(FormMain.PanelGLScene.Left, FormMain.PanelGLScene.Top,
                    FormMain.PanelGLScene.Left + FormMain.PanelGLScene.Width-1,
                    FormMain.PanelGLScene.Top  + FormMain.PanelGLScene.Height-1) );

        JPEG.Assign(Bitmap);
        JPEG.SaveToFile(FormMain.SavePictureDialog.FileName);
      finally
        JPEG.Free
      end
    end else  // end jpeg type - if bmp type
    if  Extension = '.BMP' then begin
      Bitmap := TBitmap.Create;
      try
        Bitmap.Width  := FormMain.PanelGLScene.Width; //- FormMain.CoolBar1.Width;
        Bitmap.Height := FormMain.PanelGLScene.Height - FormMain.CoolBar1.Height;
        Bitmap.PixelFormat := pf24bit;  // avoid palettes
        // Copy the Panel area from the Form into a separate Bitmap
        Bitmap.Canvas.CopyRect(Rect(0,0, Bitmap.Width,Bitmap.Height),
                  FormMain.Canvas,
                  Rect(FormMain.PanelGLScene.Left, FormMain.PanelGLScene.Top,
                  FormMain.PanelGLScene.Left + FormMain.PanelGLScene.Width-1,
                  FormMain.PanelGLScene.Top  + FormMain.PanelGLScene.Height-1) );

        Bitmap.SaveToFile(FormMain.SavePictureDialog.FileName);
      finally
        Bitmap.Free
      end;    // end try
    end;      // end extension
  end;        // end SavePictureDialog.Execute
end;
Avatar billede martinlind Nybegynder
03. august 2002 - 12:57 #1
Du kan jo f.eks. lade være med at gemme dit "skræm bitmap" der må jo være en fatal design fejl i det PanelGLScene du bruger, den bør havde en intern buffer som er den man "tegner" i, opdatering til skærmen foregår så ved at men bare laver en copy fra buffer til skærm, og skal du have bitmap'en ud læser du fra bufferen og IKKE fra skærmen, så undgår man at få en sort firkant der hvor der har været et andet vindue.

/Martin
Avatar billede lanstorp Nybegynder
03. august 2002 - 13:04 #2
Problemet er at min Opengl scene ikke findes i bufferen. Bufferen indeholder kun et tomt panel.
Avatar billede martinlind Nybegynder
03. august 2002 - 13:11 #3
kan du ikke få den ned i bufferen, der må som jeg sagde være et design problem med koden, det er nok det du skal løse hvis det skal ha' noget ordenlig kode når du er færdig
Avatar billede lanstorp Nybegynder
03. august 2002 - 14:00 #4
Tager i først omgang den nemme løsning med at flytte MessageDlg ned til lige før Bitmap.SaveToFile(FormMain.SavePictureDialog.FileName);
Selv om det ikke er en smuk løsning.
Avatar billede zerohero Nybegynder
03. august 2002 - 14:07 #5
Prøv at bruge en TImage til at vise dine bitmaps!!! Jeg mener jeg engang havde lign. problem og løste det ved at bruge en TImage... med mindre du insistere på at bruge en TPanel ;-))
Avatar billede zerohero Nybegynder
03. august 2002 - 14:10 #6
Ellers kan du jo bare lade OpenGL vise bitmappen, så er du da helt sikker på at problemet bliver løst - lav eventuelt en polygon, hvor glDisable(gl_Lighting) påvirker polygonen og brug TBitmap'en som textur!!! - bare et foreslag
Avatar billede martinlind Nybegynder
03. august 2002 - 14:11 #7
Kender ikke til OpenGL, men det lyder som en god ide med en TImage eller måske en TPaintBox du kan jo smide dem på en panel hvis du vil havde panels
Avatar billede lanstorp Nybegynder
03. august 2002 - 14:17 #8
Takker, det vil jeg have i mente.

>>zerohero, dine udmærkede tutorials fik mig iøvrigt igang med det geniale OpenGL bibliotek :)
Avatar billede zerohero Nybegynder
03. august 2002 - 14:19 #9
Det er jeg glad for at høre... :-))
Avatar billede zerohero Nybegynder
03. august 2002 - 14:24 #10
Jeg har forresten (siden jeg skrev tutorial01) udviklet en OpenGLSetup() procedure der acceptere næsten alle af Delphi's komponenter til at vise OpenGL grafik, det kan være du kan bruge den til dit projekt!!!
Avatar billede lanstorp Nybegynder
03. august 2002 - 14:37 #11
Bruger en skabelon fra Jan Horn (må vektoren være med ham).
Men vil gerne se din OpenGLSetup() procedure. Den er vist ikke på dit site?
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester