[Delphi] Compressed jpeg naar bitmap werkt niet

Pagina: 1
Acties:
  • 108 views sinds 30-01-2008
  • Reageer

Acties:
  • 0 Henk 'm!

  • Bergen
  • Registratie: Maart 2001
  • Laatst online: 07-09 11:44

Bergen

Spellingscontroleur

Topicstarter
Ik heb een stukje code die een bitmap inlaadt, die omzet naar een jpeg, dan inpakt, vervolgens weer teruggooit in de bitmap en dan opslaat. Maar er is helemaal geen spoor van compressie terug te vinden in de outputbitmap! Al gezocht naar conversiedingen op 't net, maar overal staat alleen maar hoe je een jpeg naar bitmap omzet, niet hoe je hem omzet NA compressie want het lijkt alsof ie in een aparte jpegbuffer komt ofzoiets. Probeer het maar eens. Dit is mijn code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var
      Bmp: TBitmap;
      Jpg: TJpegImage;
begin
      // create
      Bmp := TBitmap.Create;
      Jpg := TJpegImage.Create;
      // process image
      Bmp.LoadFromFile ('test1.bmp');
      Jpg.Assign (Bmp);
      Jpg.CompressionQuality := 5;
      Jpg.Compress;
      Bmp.Canvas.Draw (0, 0, Jpg);
      Bmp.SaveToFile ('test2.bmp');
      // free
      Bmp.Free;
      Jpg.Free;
end;

Acties:
  • 0 Henk 'm!

  • Bergen
  • Registratie: Maart 2001
  • Laatst online: 07-09 11:44

Bergen

Spellingscontroleur

Topicstarter
Hmm ik heb zelf al wel een oplossing gevonden maar hij's absoluut niet mooi:

Na Jpg.Compress sla ik hem direct op naar temp.jpg en laad ik hem meteen ook weer in. Lelijk ja :P Kan vast wel anders.

Acties:
  • 0 Henk 'm!

  • dusty
  • Registratie: Mei 2000
  • Laatst online: 15-09 18:24

dusty

Celebrate Life!

Ik zou zeggen ga eens onderzoeken wat JPG compressie precies doet.

Ik beveel ook aan om eens te kijken hoe de BMP structuur inelkaar zit.

Back In Black!
"Je moet haar alleen aan de ketting leggen" - MueR


Acties:
  • 0 Henk 'm!

  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 21:10

Tomatoman

Fulltime prutser

Na een hoop trial and error heb ik ooit uitgevonden dat je bij conversie van een bitmap naar JPEG goed moet opletten wat er met de pixeldata gebeurt. Een JPEG kun je niet straffeloos bewerken. Ik heb wat oude code verbouwd om aan te geven hoe dit allemaal werkt.

Bitmap naar JPEG:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
uses
  jpeg;

procedure BmpToJPEG(Bmp: TBitmap): TJPEGImage;
var
  JPEGImage: TJPEGImage;
  Img: TImage;
begin
  JPEGImage := TJPEGImage.Create;
  try
    GetDesktopScreenshot(Img);
    JPEGImage.Assign(Img.Picture.Bitmap); // Creates a DIB, no JPEG

    { Change settings that preserve the DIB. }
    JPEGImage.ProgressiveEncoding := True;
    JPEGImage.ProgressiveDisplay := True;
    JPEGImage.CompressionQuality := 50;

    { Changing the scale forces the DIB to be deleted. Create a JPEG, then
    change the scale and finally recreate a new DIB. }
    JPEGImage.JPEGNeeded;
    JPEGImage.Scale := jsHalfSize;
    JPEGImage.DIBNeeded;

    { Use the DIB to create a compressed JPEG. }
    JPEGImage.Compress;

    Result := JPEGImage;
  except
    JPEGImage.Free;
    Result := nil;
  end;
end;

JPEG weergeven in een TImage control:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
type
  TShowImage = class(TForm)
    ImageScreenshot: TImage;
    StatusBar: TStatusBar;          // met 4 panels
    SavePictureDialog: TSavePictureDialog;
    ...
  end;

resourcestring
  SJPEGCaption = 'Desktop snapshot (IP address %s)';
  SPictDimensions = '%d × %d';
  SPictQuality = 'Quality: %d%%';
  SPictImageSize = '%.0n kB';
  SPictScale = '| Desktop snapshot retrieved at %s size';
  SPictFull = 'full';
  SPictHalf = '50% of full';
  SPictQuarter = '25% of full';
  SPictEighth = '12.5% of full';

procedure TShowImage.ShowJPEG(Img: TJPEGImage);
begin
  try
    ImageScreenshot.Picture.Assign(Img);

    { nu wat eigenschappen weergeven op de statusbalk }
    with TJPEGImage(ImageScreenshot.Picture.Graphic) do
    begin
    StatusBar.Panels[0].Text := Format(SPictDimensions, [Width, Height]);
    StatusBar.Panels[1].Text := Format(SPictQuality, [CompressionQuality]);
    StatusBar.Panels[2].Text := Format(SPictImageSize, [ImageSize /1024]);
    end;
    case JPEGImage.Scale of
    jsFullSize: StatusBar.Panels[3].Text := Format(SPictScale, [SPictFull]);
    jsHalf:     StatusBar.Panels[3].Text := Format(SPictScale, [SPictHalf]);
    jsQuarter:  StatusBar.Panels[3].Text := Format(SPictScale, [SPictQuarter]);
    jsEighth:   StatusBar.Panels[3].Text := Format(SPictScale, [SPictEighth]);
    end;
  except
    on EInvalidGraphic do
    ImageScreenshot.Picture.Graphic := nil;
  end;
end;

Opslaan als JPEG of als bitmap, afhankelijk van de gekozen extensie:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
function TShowImage.SaveImage: Boolean;
var
  Ext: string;
begin
  Result := False;
  with SavePictureDialog do
    FileName := ExtractFilePath(FileName) + ExtractFileName(FileName);
  if SavePictureDialog.Execute then
  begin
    Ext := LowerCase(ExtractFileExt(SavePictureDialog.FileName));
    if Ext = '' then
    begin
    case SavePictureDialog.FilterIndex of
      1, 2: SavePictureDialog.FileName := SavePictureDialog.FileName + '.jpg';
      3   : SavePictureDialog.FileName := SavePictureDialog.FileName + '.jpeg';
    else
      SavePictureDialog.FileName := SavePictureDialog.FileName + '.bmp';
    end;
    Ext := LowerCase(ExtractFileExt(SavePictureDialog.FileName));
    end;
    if (Ext = '.jpg') or (Ext = '.jpeg') then
    with ImageScreenshot.Picture.Graphic as TJPEGImage do
      SaveToFile(SavePictureDialog.FileName)
    else
    with TBitmap.Create do
    try
      Assign(ImageScreenshot.Picture.Graphic as TJPEGImage);
      SaveToFile(SavePictureDialog.FileName);
    finally
      Free;
    end;
    Result := True;
  end;
end;

TJPEGImage slaat sommige eigenschappen trouwens niet op en leest ze ook niet terug als je een JPEG opent! Dat geldt bijvoorbeeld voor de Scale property, CompressionQuality en ImageSize.

Een goede grap mag vrienden kosten.


Acties:
  • 0 Henk 'm!

  • Bergen
  • Registratie: Maart 2001
  • Laatst online: 07-09 11:44

Bergen

Spellingscontroleur

Topicstarter
Op maandag 15 april 2002 00:27 schreef dusty het volgende:
Ik zou zeggen ga eens onderzoeken wat JPG compressie precies doet.

Ik beveel ook aan om eens te kijken hoe de BMP structuur inelkaar zit.
Hoe JPEG compressie werkt en hoe een BMP inelkaar zit weet ik allemaal wel.. daar heb ik ook weinig aan op dit moment. Hij compresst namelijk wel he.. het vage is alleen dat ie de gecompresste inhoud niet kopieerde naar de BMP, maar de originele inhoud.

Affijn, thanx Tomatoman :) Daarmee kom ik er geloof ik wel uit. De oorzaak lijkt te liggen bij het verschil in assignen.

Acties:
  • 0 Henk 'm!

Verwijderd

Ik denk dat jij alleen de property PixelFormat van de TBitmap veranderd hebt.

Acties:
  • 0 Henk 'm!

  • Bergen
  • Registratie: Maart 2001
  • Laatst online: 07-09 11:44

Bergen

Spellingscontroleur

Topicstarter
Op maandag 15 april 2002 20:51 schreef DiFool het volgende:
Ik denk dat jij alleen de property PixelFormat van de TBitmap veranderd hebt.
Nee, alles is gewoon pf24bit. Waarom zou ik die veranderen?

Acties:
  • 0 Henk 'm!

Verwijderd

Als je PixelFormat pf24bit blijft, zal een bitmap per pixel 24 bits gebruiken; dus zal een plaatje van een bepaalde breedte en grootte altijd 1 bepaalde size hebben.

Acties:
  • 0 Henk 'm!

  • Bergen
  • Registratie: Maart 2001
  • Laatst online: 07-09 11:44

Bergen

Spellingscontroleur

Topicstarter
Op donderdag 18 april 2002 19:26 schreef DiFool het volgende:
Als je PixelFormat pf24bit blijft, zal een bitmap per pixel 24 bits gebruiken; dus zal een plaatje van een bepaalde breedte en grootte altijd 1 bepaalde size hebben.
Oh zo bedoel je, maar daar doelde ik niet op... Ik bedoelde niet de verandering in grootte na de compressie, maar het verschil in zichtbare verandering. Hij bleef na compressie (ook zware) exact gelijk.
Pagina: 1