Entwickler-Ecke

Multimedia / Grafik - aus graustufen bild schwarz-weiss bild machen


Rool - Do 28.08.03 12:36
Titel: aus graustufen bild schwarz-weiss bild machen
wie kann ich so schnell wie möglich aus einem graustufen bitmap ein SW-Bitmap machen?


ShadowThief - Do 28.08.03 15:06

du schaust nach, ob der grauwert unter einer bestimmten grenze liegt,
dann punkt mchst du dann schwarz, und wenn er über der grenze
liegt machst du ihn weiss.

shadow.


DaRkFiRe - Do 28.08.03 16:09

Kann ich nur zustimmen - an dem Grenzwert kannst Du später auch die Gewichtung des S/W-Bildes regeln.


Phantom1 - Do 28.08.03 17:13

Code ist nicht getestet, value ist der Grenzwert 0 bis 255, funktioniert sogar mit farbigen bildern:


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
Procedure TForm1.BmpToSW(Bmp: TBitmap; Value: Integer);
Type
  TRGBArray = Array[0..0] of Packed Record b, g, r: byte End;
Var
  x,y, R,G,B, m: Integer;
  BmpSL: ^TRGBArray;
Begin
  Bmp.PixelFormat:=pf24bit;
  If Value<0 Then Value:=0 Else If Value>255 Then Value:=255;
  For y := 0 to Bmp.Height-1 Do Begin
    BmpSL:=Bmp.ScanLine[y];
    For x := 0 to Bmp.Width-1 do begin
      R:=BmpSL[x].r;
      G:=BmpSL[x].g;
      B:=BmpSL[x].b;
      m:=(R+G+B) Div 3;
      If m<=Value Then m:=0 Else m:=255;
      BmpSL[x].r:=m;
      BmpSL[x].g:=m;
      BmpSL[x].b:=m;
    End;
  End;
End;


Matthias - Do 28.08.03 19:38

zu der Lösung von Phantom1 noch eine Anmerkung. Da das Bild schon aus Graustufen besteht, ist das Bestimmen der Mittelwertes aus RGB nicht notwendig. Es reicht aus z.B. nur die rote Farbe zu verwenden.

Bei großen Bildern ist es noch effizenter vorher ein Feld, welches 256 Werte enthält, zu berechnen und anschließend den Wert nur noch indiziert zu übergeben.

Schwelle : array[0..255] of byte;
...

for z := 0 to 127 do Schwelle[z] := 0; // Schwellwert = 128
for z := 128 to 255 do Schwelle[z] := 255;

...

BmpSl[x].r := Schwelle[BmpSl[x].r];

...

Matthias


umpani - Do 28.08.03 21:30

Ich habe schon viele "vergrauungs" Funktionen probiert.

Das beste Ergebniss hatte ich mit dieser (kann man sicherlich auch mit Scanline machen)

Zitat:
var Grayshade, Red, Green, Blue: Byte;
PixelColor: Longint;



Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
    with bitmap do
     for i := 0 to Width - 1 do 
      for j := 0 to Height - 1 do 
      begin
        PixelColor := ColorToRGB(Canvas.Pixels[i, j]);
        Red        := PixelColor; 
        Green      := PixelColor shr 8; 
        Blue       := PixelColor shr 16; 
        Grayshade  := Round(0.3 * Red + 0.6 * Green + 0.1 * Blue);
        Canvas.Pixels[i, j] := RGB(Grayshade, Grayshade, Grayshade);
      end;


Die verschiedenen Werte bei der Farbberechnung resultieren aus den verschiedenen Helligkeitswidergaben im S/W Bild