| Autor |
Beitrag |
Wolle92
      
Beiträge: 1296
Windows Vista Home Premium
Delphi 7 PE, Delphi 7 Portable, bald C++ & DirectX
|
Verfasst: So 08.02.09 19:38
Hallo,
ich hab schon gesucht, aber nichts Brauchbares gefunden...
Also ich suche nach einem Algorithmus, mit dem ich farbige Bilder in schwarz/weiß-Bilder bzw. in Sepia-Bilder umrechnen kann...
Kann mir da jemand weiterhelfen?
Grüße,
Wolle
_________________ 1405006117752879898543142606244511569936384000000000.
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 08.02.09 19:39
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: So 08.02.09 19:42
Dazu gehst Du Pixelweise durch das Bild durch (ggf. mit Scanline für die Performance) und errechnest für jeden RGB-Pixel in den L-Kanal (bei HSL oder Y-Kanal bei YUV) um.
Mehr Infos zu den Farbsystemen unter www.verwaltung.uni-m...grokking/node52.html
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Gausi
      
Beiträge: 8554
Erhaltene Danke: 481
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Mo 09.02.09 08:48
Und wenn es wirklich schwarz-weiß sein soll, und nicht in Graustufen, dann kann man dithern. Der Code ist schon etwas älter, kann gut sein, dass der nicht ganz optimal gestaltet ist.
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: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75:
| function GetClosestColor(b,g,r:integer):integer; begin if ((b+g+r) DIV 3) > 128 then result := 255 else result := 0; end;
procedure AddError(var b,g,r:byte; bdif,gdif,rdif:double); var btmp,rtmp,gtmp:integer; begin btmp:=b; gtmp:=g; rtmp:=r;
btmp:=round(b-bdif); if btmp<0 then b:=0 else if btmp>255 then b:=255 else b:=btmp;
gtmp:=round(g-gdif); if gtmp<0 then g:=0 else if gtmp>255 then g:=255 else g:=gtmp;
rtmp:=round(r-rdif); if rtmp<0 then r:=0 else if rtmp>255 then r:=255 else r:=rtmp; end;
procedure Dithering(aBitmap:TBitmap); var Zeile1,Zeile2 : PByteArray; x,y:integer; rdif,gdif,bdif:integer; closestcolor:integer; begin for y:= 0 to aBitmap.Height -1 do begin Zeile1 := aBitmap.Scanline[y]; if y<aBitmap.Height-1 then zeile2:=aBitmap.Scanline[y+1]; for x := 0 to aBitmap.Width -1 do begin closestcolor:=getClosestColor(Zeile1[3*x],Zeile1[3*x+1],Zeile1[3*x+2]); bdif:=closestcolor-Zeile1[3*x]; gdif:=closestcolor-Zeile1[3*x+1]; rdif:=closestcolor-Zeile1[3*x+2]; Zeile1[3*x]:=closestcolor; Zeile1[3*x+1]:=closestcolor; Zeile1[3*x+2]:=closestcolor; if x<aBitmap.Width-1 then AddError( Zeile1[3*x+3],Zeile1[3*x+4],Zeile1[3*x+5], bdif*7/16,gdif*7/16,rdif*7/16); if y<aBitmap.Height-1 then begin AddError( Zeile2[3*x],Zeile2[3*x+1],Zeile2[3*x+2], bdif*5/16,gdif*5/16,rdif*5/16); if x<aBitmap.Width-1 then AddError( Zeile2[3*x+3],Zeile2[3*x+4],Zeile2[3*x+5], bdif*1/16,gdif*1/16,rdif*1/16); if x>0 then AddError( Zeile2[3*x-3],Zeile2[3*x-2],Zeile2[3*x-1], bdif*3/16,gdif*3/16,rdif*3/16); end; end; end; end; |
Ich werte hier zwar die rgb-Werte alle gleich, aber trotzdem sind die Ergebnisse erstaunlich gut.
_________________ We are, we were and will not be.
|
|
Gummibär
      
Beiträge: 18
Erhaltene Danke: 11
Delphi 7, Turbo Delphi
|
Verfasst: Mo 09.02.09 09:19
Sowas ähnliches hatten wir in der Delphi-Praxis schon mal: Blaustufen (statt Sepia).
Das Codebeispiel müßtest Du mit Deinem Bitmap (32bit Fabtiefe!) und der gewünschten Zielfarbe aufrufen: ConvertBitmap32(Bitmap, $005ECCFF);. (Keine Ahnung, ob $005ECCFF ein brauchbares Sepia ergibt...)
Gruß
Michael
|
|
|