Autor Beitrag
Wolle92
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 1296

Windows Vista Home Premium
Delphi 7 PE, Delphi 7 Portable, bald C++ & DirectX
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 08.02.09 19:39 
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8554
Erhaltene Danke: 481

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: 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. ;-)

ausblenden volle Höhe Delphi-Quelltext
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
      // aktuellen Pixel reduzieren
      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;
      // Dithering
      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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 18
Erhaltene Danke: 11


Delphi 7, Turbo Delphi
BeitragVerfasst: 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