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.