// 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