// Farbige Bitmaps werden grau bzw. schwarz/weiß angezeigt. // Getestet mit D4 unter WinME 1. Graustufen-Bilder
1.1. 256
Graustufen aber 24 BpP
2. Monochrom-Bilder
2.1.
Monochrom aber 24 BpP
//
256 Graustufen aber 24 BpP procedure grau_256_24(Source, Dest: TBitmap);
var
x, y, br: integer;
pd: PBytearray;
begin
Dest.pixelformat := pf24bit;
br := Source.width * 3 - 1;
Dest.width := Source.width;
Dest.height := Source.height;
Dest.canvas.draw(0, 0, Source);
for y := 0 to Dest.height - 1 do begin
pd := Dest.ScanLine[y];
x := 0;
while x < br do begin
pd[x] := (pd[x + 2] * 77 + pd[x + 1] * 151 + pd[x] * 28) shr 8;
pd[x + 1] := pd[x];
pd[x + 2] := pd[x];
inc(x, 3);
end;
end;
end;
//
256 Graustufen und 8 BpP mit Streams type
RGBQ = array[0..0] of RGBQUAD;
PRGBQ = ^RGBQ;
function Weiter(p: Pointer; plus: Integer): PByte;
begin
Result := p;
Inc(Result, plus);
end;
function breit(x: LongInt): LongInt;
begin
Result := ((x + 31) div 32) * 4;
end;
{$R-}
function grau_256_8_strm(Source, Dest: TBitmap): boolean;
var
SPal, DPal: PRGBQ;
Pal: array[Byte] of Byte;
SBFH, DBFH: PBitmapFileHeader;
SBih, DBih: PBitmapInfoHeader;
x, y, DLS, SLS, SrcWidth, SrcHeight, srcpf: LongInt;
SStream, DStream: TMemoryStream;
SPL, SrcPB, DPL, DstPB: PByte;
SP, DP: Pointer;
function GetSrcHeader: Boolean;
var
p: PByte;
BitsIndex: LongInt;
begin
Result := False;
p := SStream.Memory;
SBFH := PBitmapFileHeader(p);
if SBFH^.bfType <> $4D42 then Exit;
Inc(p, SizeOf(TBitmapFileHeader));
SBih := PBitmapInfoHeader(p);
Inc(p, SizeOf(TBitmapInfoHeader));
with SBih^ do begin
if biSize <> SizeOf(TBitmapInfoHeader) then Exit;
if biCompression <> BI_RGB then Exit;
SPal := PRGBQ(p);
BitsIndex := SBFH^.bfOffBits;
if biBitCount > 8 then Inc(BitsIndex, biClrUsed * SizeOf(RGBQuad));
SP := Weiter(SStream.Memory, BitsIndex);
SrcWidth := biWidth;
SrcHeight := biHeight;
SLS := breit(biWidth * biBitCount);
case biBitCount of
8, 24, 32: srcpf := biBitCount shr 3;
else exit;
end;
if BitsIndex + biHeight * SLS > SStream.Size then exit;
end;
Result := True;
end;
function CreateDstHeader: boolean;
var
p: PByte;
NewSize: LongInt;
i: LongInt;
begin
result := false;
try
NewSize := SizeOf(TBitmapFileHeader) + SizeOf(TBitmapInfoHeader) +
256 * SizeOf(RGBQuad) + breit(SrcWidth * 8) * SrcHeight;
DStream.SetSize(NewSize);
p := DStream.Memory;
FillChar(p^, NewSize, 0);
DBFH := PBitmapFileHeader(p);
with DBFH^ do begin
bfType := $4D42;
bfSize := NewSize;
bfOffBits := SizeOf(TBitmapFileHeader) + SizeOf(TBitmapInfoHeader) +
256 * SizeOf(RGBQuad);
end;
Inc(p, SizeOf(TBitmapFileHeader));
DBih := PBitmapInfoHeader(p);
with DBih^ do begin
biSize := SizeOf(TBitmapInfoHeader);
biWidth := SrcWidth;
biHeight := SrcHeight;
biPlanes := 1;
biBitCount := 8;
biCompression := BI_RGB;
biSizeImage := 0;
biXPelsPerMeter := 96;
biYPelsPerMeter := 96;
biClrUsed := 0;
biClrImportant := 0;
DLS := breit(biWidth * biBitCount);
end;
Inc(p, SizeOf(TBitmapInfoHeader));
DPal := PRGBQ(p);
Inc(p, 256 * SizeOf(RGBQuad));
DP := p;
for i := 0 to 255 do begin
with DPal^[i] do begin
rgbBlue := i;
rgbGreen := i;
rgbRed := i;
end;
end;
result := true;
except
exit;
end;
end;
begin
result := false;
SStream := TMemoryStream.Create;
DStream := TMemoryStream.Create;
if (Source.width = 0) or (Source.height = 0) then exit;
try
Source.SaveToStream(SStream);
if GetSrcHeader then begin
if CreateDstHeader then begin
if srcpf = 1 then begin
for x := 0 to 255 do with SPal^[x] do
Pal[x] := Byte((rgbRed * 77 + rgbGreen * 151 + rgbBlue * 28) shr
8);
SPL := SP;
DPL := DP;
for y := 0 to SrcHeight - 1 do
begin
SrcPB := SPL;
DstPB := DPL;
for x := 0 to SrcWidth - 1 do
begin
DstPB^ := Pal[SrcPB^];
Inc(SrcPB);
Inc(DstPB);
end;
Inc(SPL, SLS);
Inc(DPL, DLS);
end;
end
else begin
SPL := SP;
DPL := DP;
for y := 0 to SrcHeight - 1 do
begin
SrcPB := SPL;
DstPB := DPL;
for x := 0 to SrcWidth - 1 do
begin
with PRGBQuad(SrcPB)^ do
DstPB^ := Byte((rgbRed * 77 + rgbGreen * 151 + rgbBlue * 28) shr
8);
Inc(SrcPB, srcpf);
Inc(DstPB);
end;
Inc(SPL, SLS);
Inc(DPL, DLS);
end;
end;
DStream.Seek(0, soFromBeginning);
Dest.LoadFromStream(DStream);
result := true;
end;
end;
finally
DStream.Free;
SStream.Free;
end;
end;
//
256 Graustufen und 8 BpP mit Palette {$R-}
procedure grau_256_8_pal(Source, Dest: TBitmap);
var
lPal: PLogpalette;
i: integer;
begin
Dest.width := Source.width;
Dest.height := Source.height;
Dest.pixelformat := pf8bit;
GetMem(lpal, sizeof(TLogPalette) + sizeof(TPaletteEntry) * 256);
lpal.palVersion := $300;
lpal.palNumEntries := 256;
for i := 0 to 255 do lpal.palPalEntry[i] :=
Tpaletteentry(i or (i shl 8) or (i shl 16));
Dest.palette := CreatePalette(lpal^);
FreeMem(lpal);
Dest.canvas.draw(0, 0, Source);
end;
//
256 Graustufen und 16 BpP procedure grau_24_16(Source, Dest: TBitmap);
var
pbi: pBitmapInfo;
pSrc: pRGBQuad;
hbmp: HBitmap;
x, y: Integer;
pDst: pWord;
p: Pointer;
b: byte;
begin
Source.pixelformat := pf24bit;
pbi := AllocMem(sizeof(BITMAPINFO) + sizeof(DWord) * 3);
with pbi^.bmiHeader do
begin
biSize := sizeof(BITMAPINFOHEADER);
biPlanes := 1;
biBitCount := 16;
biWidth := Source.Width;
biHeight := Source.Height;
biCompression := BI_BITFIELDS;
end;
pWordArray(@(pbi^.bmiColors[0]))^[0] := $F800;
pWordArray(@(pbi^.bmiColors[0]))^[2] := $07E0;
pWordArray(@(pbi^.bmiColors[0]))^[4] := $001F;
hbmp := CreateDIBSection(0, pbi^, DIB_RGB_COLORS, p, 0, 0);
if hbmp <> HBITMAP(0) then
for y := 0 to Source.Height - 1 do
begin
pSrc := pRGBQuad(Source.ScanLine[y]);
pDst := pWord(Integer(p) +
((Source.Width * 2 + 3) and -4)
* (Source.Height - 1 - y));
for x := 0 to Source.Width - 1 do
begin
b := (pSrc^.rgbBlue * 77 +
pSrc^.rgbGreen * 151 + pSrc^.rgbRed * 28) shr 8;
pDst^ := (b shr 3) or ((b shr 2) shl 5) or (DWord(b shr 3) shl 11);
Inc(Integer(pSrc), 3);
Inc(pDst);
end;
end;
Dest.handle := hbmp;
FreeMem(pbi);
end;
//
16 Graustufen und 4 BpP {$R-}
procedure grau_16_4(Source, Dest: TBitmap);
var
lPal: PLogpalette;
i: integer;
begin
Dest.width := Source.width;
Dest.height := Source.height;
Dest.pixelformat := pf4bit;
GetMem(lpal, sizeof(TLogPalette) + sizeof(TPaletteEntry) * 16);
lpal.palVersion := $300;
lpal.palNumEntries := 16;
for i := 0 to 15 do lpal.palPalEntry[i] :=
Tpaletteentry((i shl 4) or (i shl 12) or (i shl 20));
Dest.palette := CreatePalette(lpal^);
FreeMem(lpal);
Dest.canvas.draw(0, 0, Source);
end;
procedure monochrom(Source, Dest: TBitmap);
var
x, y, br: integer;
pd: PBytearray;
begin
br := Source.width * 3 - 1;
Dest.width := Source.width;
Dest.height := Source.height;
Dest.pixelformat := pf24bit;
Dest.canvas.draw(0, 0, Source);
for y := 0 to Source.height - 1 do begin
pd := Dest.ScanLine[y];
x := 0;
while x < br do begin
pd[x] := $FF * ord((pd[x] + pd[x + 1] + pd[x + 2]) > 390);
pd[x + 1] := pd[x];
pd[x + 2] := pd[x];
inc(x, 3);
end;
end;
end;
// Monochrom und 1 BpP procedure monochrom1(Source, Dest: TBitmap);
begin
Dest.handle := copyimage(Source.handle, IMAGE_BITMAP, 0, 0,
LR_COPYRETURNORG or LR_MONOCHROME);
Dest.pixelformat := pf1bit;
end;
// Monochrom3 und 1 BpP procedure monochrom3(Source, Dest: TBitmap);
var
x, y, br: integer;
p: PBytearray;
begin
br := Source.width * 3 - 1;
Dest.width := Source.width;
Dest.height := Source.height;
Dest.pixelformat := pf24bit;
Dest.canvas.draw(0, 0, Source);
for y := 0 to Source.height - 1 do begin
x := 0;
p := Dest.scanline[y];
while x < br do begin
if (p[x] + p[x + 1] + p[x + 2] + $FF * ord(odd(x xor y))) < 512
then p[x] := 0 else p[x] := $FF;
p[x + 1] := p[x];
p[x + 2] := p[x];
inc(x, 3);
end;
end;
Dest.handle := copyimage(Dest.handle, IMAGE_BITMAP, 0, 0,
LR_COPYRETURNORG or LR_MONOCHROME);
Dest.pixelformat := pf1bit;
end;
//
Monochrom4 und 1 BpP procedure monochrom4(Source, Dest: TBitmap);
var
x, y, z, b, h: integer;
p: pbytearray;
f, g: integer;
begin
Dest.width := Source.width;
Dest.height := Source.height;
Dest.pixelformat := pf24bit;
Dest.canvas.draw(0, 0, Source);
b := Source.width * 3 - 1;
h := Source.height - 1;
y := 0;
while y <= h do begin
x := 0;
p := Dest.scanline[y];
while x < b do begin
g := (p[x + 2] + p[x + 1] + p[x]) div 3;
if g < 128 then begin
f := g;
for z := 0 to 2 do
p[x + z] := 0;
for z := 3 to 5 do
g := (g + p[x + z]);
g := g div 3 + f;
end else begin
f := (256 - g) * 2;
for z := 0 to 2 do
p[x + z] := 255;
for z := 3 to 5 do
g := (g + p[x + z]);
g := g div 3 - f;
end;
for z := 3 to 5 do p[x + z] := ord(g > 128) * 255;
inc(x, 6);
end;
inc(y, 2);
end;
Dest.handle := copyimage(Dest.handle, IMAGE_BITMAP, 0, 0,
LR_COPYRETURNORG or LR_MONOCHROME);
Dest.pixelformat := pf1bit;
end;
//
Monochrom5 und 1 BpP var
schablone: array[0..4] of TBitmap;
procedure schablonen;
var i: integer;
begin
for i := 0 to 4 do begin
schablone[i] := TBitmap.create;
with schablone[i] do begin
width := 2;
height := 2;
with canvas do begin
brush.color := ord(i < 3) * $FFFFFF;
fillrect(cliprect);
end;
end;
end;
for i := 1 to 3 do begin
with schablone[i].canvas do begin
case i of
1: pixels[0, 0] := 0;
2: begin
pixels[0, 0] := 0;
pixels[1, 1] := 0;
end;
3: pixels[0, 1] := $FFFFFF;
end;
end;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
schablonen;
end;
procedure TForm1.FormDestroy(Sender: TObject);
var x: integer;
begin
for x := 0 to 4 do schablone[x].free;
end;
procedure monochrom5(Source, Dest: TBitmap);
var
x, y, z, b, h: integer;
p: pbytearray;
g: word;
begin
Dest.width := Source.width;
Dest.height := Source.height;
Dest.pixelformat := pf24bit;
Dest.canvas.draw(0, 0, Source);
b := Source.width * 3 - 1;
h := Source.height - 1;
y := 0;
with Dest.canvas do begin
while y <= h do begin
x := 0;
while x < b do begin
g := 0;
p := Dest.scanline[y];
for z := 0 to 5 do
g := g + p[x + z];
if y = h then g := g * 2 else begin
p := Dest.scanline[y + 1];
for z := 0 to 5 do
g := g + p[x + z];
end;
case g of
0..655: draw(x div 3, y, schablone[4]);
656..1330: draw(x div 3, y, schablone[3]);
1331..2000: draw(x div 3, y, schablone[2]);
2001..2490: draw(x div 3, y, schablone[1]);
else draw(x div 3, y, schablone[0]);
end;
inc(x, 6);
end;
inc(y, 2);
end;
end;
Dest.handle := copyimage(Dest.handle, IMAGE_BITMAP, 0, 0,
LR_COPYRETURNORG or LR_MONOCHROME);
Dest.pixelformat := pf1bit;
end;
//
Pattern procedure pattern(Source, Dest: TBitmap);
var
x, y, b: integer;
z: byte;
p: pbytearray;
const
muster: array[0..1, 0..1] of byte =
(($83, $55), ($20, $A3));
begin
Dest.width := Source.width;
Dest.height := Source.height;
Dest.pixelformat := pf24bit;
Dest.canvas.draw(0, 0, Source);
b := Source.width * 3 - 1;
for y := 0 to source.height - 1 do begin
x := 0;
p := Dest.scanline[y];
while x < b do begin
z := muster[(x div 3) mod 3, y mod 3];
p[x] := (p[x] + z) shr 1;
p[x + 1] := (p[x + 1] + z) shr 1;
p[x + 2] := (p[x + 2] + z) shr 1;
inc(x, 3);
end;
end;
Dest.handle := copyimage(Dest.handle, IMAGE_BITMAP, 0, 0,
LR_COPYRETURNORG or LR_MONOCHROME);
Dest.pixelformat := pf1bit;
end;
//
Diffusion procedure Diffusion(Source, Dest: TBitmap);
var
x, y, x3: integer;
arr: array of array of single;
p: PByteArray;
t: single;
begin
Dest.width := Source.width;
Dest.height := Source.height;
Dest.pixelformat := pf24bit;
Dest.canvas.draw(0, 0, Source);
setlength(arr, Dest.height, Dest.width);
for y := 0 to Dest.height - 1 do begin
p := dest.scanline[y];
for x := 0 to Dest.width - 1 do begin
x3 := x * 3;
arr[y, x] := (p[x3] + p[x3 + 1] + p[x3 + 2]) / 3;
end;
end;
for y := 1 to Dest.height - 2 do
for x := 1 to Dest.width - 2 do begin
if (arr[y, x] < 128) then begin
t := arr[y, x] / 16;
arr[y, x] := 0;
end else begin
t := (arr[y, x] - 255) / 16;
arr[y, x] := 1;
end;
arr[y + 1, x - 1] := arr[y + 1, x - 1] + t * 3;
arr[y + 1, x] := arr[y + 1, x] + t * 5;
arr[y + 1, x + 1] := arr[y + 1, x + 1] + t;
arr[y, x + 1] := arr[y, x + 1] + t * 7;
end;
for y := 0 to Dest.height - 1 do begin
p := dest.scanline[y];
for x := 0 to Dest.width - 1 do begin
x3 := x * 3;
if arr[y, x] = 0 then p[x3] := 0 else p[x3] := 255;
p[x3 + 1] := p[x3];
p[x3 + 2] := p[x3];
end;
end;
arr := nil;
Dest.handle := copyimage(Dest.handle, IMAGE_BITMAP, 0, 0,
LR_COPYRETURNORG or LR_MONOCHROME);
Dest.pixelformat := pf1bit;
end;
// Ordered Dither |
Zugriffe seit 6.9.2001 auf Delphi-Ecke





