AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi PNG Semitransparenz aus Schwarz/Grau/weiß etc berechnen
Thema durchsuchen
Ansicht
Themen-Optionen

PNG Semitransparenz aus Schwarz/Grau/weiß etc berechnen

Ein Thema von Memnarch · begonnen am 14. Jan 2011 · letzter Beitrag vom 15. Jan 2011
Antwort Antwort
Benutzerbild von Memnarch
Memnarch

Registriert seit: 24. Sep 2010
737 Beiträge
 
#1

PNG Semitransparenz aus Schwarz/Grau/weiß etc berechnen

  Alt 14. Jan 2011, 23:05
Nabend, ich mal wieder^^.

Eigentlich suchte ich nach einem prog, das wie GIMP eine Farbe(zb weiß) für transparenz nimt und damit auch semitransparenz erstellen kann.
Wnen ich in Gimp z.B nen gradient von schwarz nach weiß habe und weiß als "Transparenz aus Farbe" nutze, erhalte ich einen Alphatransparenz verlauf von durchsichtig nach undurchsichtig.

Problem: Ich habe hunderte von files, da gehts schlecht per hand. Alle batch process Programme die ich fand konnten nur Durchsichtig/Undurchsichtig aber keine Semitransparenz erstellen.

Also dachte ich es wäre super dass dan vllt in Delphi zu erledigen(außer einer hat son prog für mich^^). Das ganze brauch natürlich nicht in echtzeit sein, dafür sinds zuviele, aber ich möchte ne schöne Semitransparenz berechnen.

Also mit scanline&co komme ich ja nun an die Daten der Pixel. Aber irgendwie komm ich noch nicht ganz weiter. Was muss ich machen um z.B. bei einem PNG das noch keinen hat, den alphakanal hinzuzufügen/aktivieren?

MFG
Memnarch
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#2

AW: PNG Semitransparenz aus Schwarz/Grau/weiß etc berechnen

  Alt 14. Jan 2011, 23:56
Die beiliegende Routine dient dazu BMP's mit Alphakanalinfo's in PNG's zu speichern.
Nicht ganz das was Du brauchst, aber Du kannst erkennen wie es funktioniert und es für Deine Zwecke umschreiben.
Delphi-Quellcode:
function PNG4TransparentBitMap(bmp:TBitmap):TPNGImage;
//201011 Thomas Wassermann
var
  x, y:Integer;
  vBmpRGBA: ^TRGBAArray;
  vPngRGB: ^TRGB;
begin
  Result := TPNGImage.CreateBlank(COLOR_RGBALPHA, 8, bmp.Width , bmp.Height);
  Result.CreateAlpha;
  Result.Canvas.CopyMode:= cmSrcCopy;
  Result.Canvas.Draw(0,0,bmp);

  for y := 0 to pred(bmp.Height) do begin
    vBmpRGBA := bmp.ScanLine[y];
    vPngRGB:= Result.Scanline[y];

    for x := 0 to pred(bmp.width) do begin
      Result.AlphaScanline[y][x] := vBmpRGBA[x].A;
      if bmp.AlphaFormat in [afDefined,afPremultiplied] then begin
        if vBmpRGBA[x].A <> 0 then begin
          vPngRGB^.b:= round(vBmpRGBA[x].b/vBmpRGBA[x].A*255);
          vPngRGB^.r:= round(vBmpRGBA[x].r/vBmpRGBA[x].A*255);
          vPngRGB^.g:= round(vBmpRGBA[x].g/vBmpRGBA[x].A*255);
        end else begin
          vPngRGB^.b:= round(vBmpRGBA[x].b*255);
          vPngRGB^.r:= round(vBmpRGBA[x].r*255);
          vPngRGB^.g:= round(vBmpRGBA[x].g*255);
        end;
      end;
      inc(vPngRGB);
    end;
  end;
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Benutzerbild von Memnarch
Memnarch

Registriert seit: 24. Sep 2010
737 Beiträge
 
#3

AW: PNG Semitransparenz aus Schwarz/Grau/weiß etc berechnen

  Alt 15. Jan 2011, 17:50
Vielen dank, werde ich mir merken

Zwischenzeitlich bin ich auch auf den Trichter gekommen einfach alles in Vegas reinzuwerfen und da die Alpha Maske berechnen zu lassen .
Da bekomm ich dan auch klase semitransparenz^^"

Aber obiges beispiel kommt aufjedenfall in meine schnippselsammlung

MFG
Memnarch
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#4

AW: PNG Semitransparenz aus Schwarz/Grau/weiß etc berechnen

  Alt 15. Jan 2011, 18:23
Diesen Code habe ich mal geschrieben. Genutzt wird hier TBitmap32 aus der Graphics32-Bibliothek, sollte sich aber einfach auf das Standard-TBitmap umschreiben lassen:
Delphi-Quellcode:
function RestoreOriginalValue(const ValueOnBlack, ValueOnWhite: integer;
  MaxValue: integer; Alpha: integer; MaxAlpha: integer): integer; inline;
// Meine Herleitung, die hier aber nicht verwendet wird, weil sie als Ergebnis Mist liefert (s.u.)
// I d1 = c0*a + c1*(1-a)
// II d2 = c0*a + c2*(1-a)
//
// d1 = c0*a + c1*(1-a) | -c1*(1-a)
// III d1-c1*(1-a) = c0*a
//
// d2 = c0*a + c2*(1-a) | -c2*(1-a)
// IV d2-c2*(1-a) = c0*a
//
// III + IV
// d1 - c1*(1-a) + d2 - c2*(1-a) = 2*c0*a
// d1 + d2 - (1-a)(c1+c2) = 2*c0*a | /2
// (d1 + d2 - (1-a)(c1+c2))/(2a) = c0
//var
// Tmp: double;
begin
  if IsZero(Alpha) then
    raise Exception.Create('Cannot define Color because alpha=0')
  else
  begin
// Meine selbst hergleitete Formel, die schlechte Ergebnisse liefert:
// Tmp := (ValueOnBlack + ValueOnWhite - MaxValue + Alpha)*MaxAlpha/(2*Alpha);
// Result := Round(Tmp);
// Von ZScreen geklaute Formel[*]:
    Result := (ValueOnBlack * MaxValue) div Alpha;
  end;
//[*] http://code.google.com/p/zscreen/source/browse/trunk/GraphicsManagerLib/GraphicsMgr.cs#668
end;

function RestoreTransparentColor(const ColorOnBlack: TRGB;
  const ColorOnWhite: TRGB): TRGBA; inline; overload;
var
  AlphaValue: int64;
  A: byte;
begin
  AlphaValue := 255 - (ColorOnWhite.R-ColorOnBlack.R +
                       ColorOnWhite.G-ColorOnBlack.G +
                       ColorOnWhite.B-ColorOnBlack.B ) div 3;
  A := Byte(min(255, max(0,AlphaValue)));
  Result.A := A;
  Result.R := RestoreOriginalValue(ColorOnBlack.R, ColorOnWhite.R, 255, A, 255);
  Result.G := RestoreOriginalValue(ColorOnBlack.G, ColorOnWhite.G, 255, A, 255);
  Result.B := RestoreOriginalValue(ColorOnBlack.B, ColorOnWhite.B, 255, A, 255);
end;

function RestoreTransparentColor(const ColorOnBlack: TColor32;
  const ColorOnWhite: TColor32): TColor32; inline; overload;
var
  AlphaValue: int64;
  A: byte;
  R1,G1,B1,
  R2,G2,B2: byte;
begin
  R1 := GetRValue(ColorOnWhite);
  G1 := GetGValue(ColorOnWhite);
  B1 := GetBValue(ColorOnWhite);
  R2 := GetRValue(ColorOnBlack);
  G2 := GetGValue(ColorOnBlack);
  B2 := GetBValue(ColorOnBlack);
  AlphaValue := 255 - (R1-R2 + G1-G2 + B1-B2 ) div 3;
  A := Byte(min(255, max(0,AlphaValue)));
  if A = 255 then
    Result := SetAlpha(ColorOnBlack,255) // oder ColorOnWhite...
  else if A>0 then
  begin
    Result := Color32(
      RestoreOriginalValue(B2, B1, 255, A, 255),
      RestoreOriginalValue(G2, G1, 255, A, 255),
      RestoreOriginalValue(R2, R1, 255, A, 255),
      R2-R1+255
    );
  end
  else
    Result := Gray32(0,0);
end;

procedure RestoreAlphaChannel(const BmpBlack, BmpWhite: TBitmap32;
  const Dest: TBitmap32);
var
  PtrBlack,
  PtrWhite,
  PtrDest: PColor32;
  EndPtr: PColor32;
begin
  if (BmpBlack.Width <> BmpWhite.Width) or (BmpBlack.Height <> BmpWhite.Height) then
    Exception.Create('Bitmaps have different sizes');
  Dest.SetSize(bmpBlack.Width, BmpBlack.Height);
  PtrBlack := BmpBlack.PixelPtr[0,0];
  PtrWhite := BmpWhite.PixelPtr[0,0];
  PtrDest := Dest.PixelPtr[0,0];
  EndPtr := BmpBlack.PixelPtr[BmpBlack.Width-1, BmpBlack.Height-1];
  while PtrBlack <> EndPtr do
  begin
    PtrDest^ := RestoreTransparentColor(PtrBlack^, PtrWhite^);
    inc(PtrBlack);
    inc(PtrWhite);
    inc(PtrDest);
  end;
end;
Im Anhang eine kleine Demo-Anwendung dazu. Man kann u.a. einen Screenshot des Formulars erstellen und die Alphatransparenz des Aero-Rahmens wiederherstellen. Super dokumentiert ist der Code jetzt nicht, aber ich denke, man kann ihn als Grundlage benutzen.
Angehängte Dateien
Dateityp: zip AlphaExtraction.zip (771,3 KB, 7x aufgerufen)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:39 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz