TPNGImage - odczyt pixeli

0

Witam ! Mam obraz PNG o 48bitowej głębi koloru (po 16 bitów na kanał ). Chciałbym po załadowaniu pliku odczytać wartości pixeli i każdą paczke pixeli RGB przekonwertować na grayscale za pomocą formuły : 0.21 R + 0.71 G + 0.07 B. Nie mogę nigdzie znaleźć dokumentacji co do klasy TPNGImage . Wiem że jeżeli chce wczytać obraz w którym jest po 16 bitów na kanał należy uzyć scanline do odczytu pierwszych ośmiu bitów i extraScanline do odczytu następnych ośmiu, ale to tyle .

Chciałbym jeszcze zadać pytanie co do samej struktury pliku PNG jeżeli plik jest o szerokości 960 pikseli to w jednej linii jest tam 960 "paczek" RGB czy też 320 pikseli R, 320 pikseli G, 320 pikseli B ?

1

jeżeli plik jest o szerokości 960 pikseli to w jednej linii jest tam 960 "paczek"

W uproszczeniu tak, lecz afaik PNG posiada pewną formę kompresji, więc nie możesz powiedzieć, że jest "960" paczek, tylko co najwyżej jest ich tyle po wczytaniu i przeparsowaniu pliku.

960 "paczek" RGB czy też 320 pikseli R, 320 pikseli G, 320 pikseli B ?

Jeżeli miałbyś 320 R, 320 G oraz 320 B, w rzeczywistości obraz miałby szerokość 320 pikseli (RGB).

0

No ok rozumiem. Czyli używając czegoś takieg

 
var 
tab : pbytearray ;
begin  
    tab:= PNG.scanline[0]
end;

w tablicy tab będę miał pierwszy wiersz czyli 960x3 = 2880 wartości po kolei RGBRGBRGBRGBRGBRGBRGB.... itd ?

0

Na logikę, tak.

0

A jak mógłbym się dowiedzieć w jakiej kolejności są wartości RGB. Czy jest to własnie RGB czy BGR ? czy zawsze jest to kolejność RGB ? I jak np. sprawdzić czy czasami nie ma w pliku kanału Alfa ? Bo np wczytam jedną linie pixeli tak jak powyżej i co 3 wartości z tablicy Tab będę je konwertował na grayscale. No ale wlasnie jezeli będzie kanał alpha to będę to musiał robić co 4 wartości wyrzucając go .

1

A jak mógłbym się dowiedzieć w jakiej kolejności są wartości RGB. Czy jest to własnie RGB czy BGR ? czy zawsze jest to kolejność RGB ?

Jakbyś napisał kod testowy to byś się przekonał ale twój czas jest ważniejszy niż nasz?

Bo np wczytam jedną linie pixeli tak jak powyżej i co 3 wartości z tablicy Tab będę je konwertował na grayscale. No ale wlasnie jezeli będzie kanał alpha to będę to musiał robić co 4 wartości wyrzucając go .

To takie straszne, zmarnujesz parę godzin na modyfikację kodu?

Chciałbym jeszcze zadać pytanie co do samej struktury pliku PNG jeżeli plik jest o szerokości 960 pikseli to w jednej linii jest tam 960 "paczek" RGB czy też 320 pikseli R, 320 pikseli G, 320 pikseli B ?

Sprawdzić oczywiście nie możesz.

0

Jakbyś napisał kod testowy to byś się przekonał ale twój czas jest ważniejszy niż nasz?

Nie nie jest ważniejszy, nie wiem jak to zrobić dla tego pytam. Po wywołaniu

tab := scanline[i]

Mając wartości w tablicy "tab" jak mam sprawdzić czy jest to R , G czy B ?

To takie straszne, zmarnujesz parę godzin na modyfikację kodu?

nie. modyfikacja kodu była by faktycznie bardzo prosta jednak zastanawiałem sie czy możliwe jest zautomatyzowanie tego czy obraz zawiera czy też nie kanał alfa.

1

Mając wartości w tablicy "tab" jak mam sprawdzić czy jest to R , G czy B ?

Najłatwiej to chyba zrobić całkowicie czerwony obrazek i go wczytać :P

1

Zgodnie z dokumentacją:

http://www.w3.org/TR/PNG-DataRep.html napisał(a)

An indexed-color pixel is represented by a single sample that is an index into a supplied palette. The image bit depth determines the maximum number of palette entries, but not the color precision within the palette.
A grayscale pixel is represented by a single sample that is a grayscale level, where zero is black and the largest value for the bit depth is white.
A truecolor pixel is represented by three samples: red (zero = black, max = red) appears first, then green (zero = black, max = green), then blue (zero = black, max = blue). The bit depth specifies the size of each sample, not the total pixel size.

Zawsze jest to RGB...

1

noo tak tak , ale to akurat przekonałbym się o tym w jaki sposób ułożone są wartości RGB dla tego konkretnego obrazu a dalej bym nie znał dla innych no chyba że to zawsze jest ta sama kolejność.

Nie, zawsze jest inna, pewnie na dodatek zaszyfrowana żeby jakiś chakier tego nie złamał!
Przecież TPngImage wykona za ciebie dekompresję więc podaje ci już wszystko rozpakowane i na talerzu. Ale ty chyba nie rozumiesz tego...

0

mogę prosić Cie o niewypowiadanie się w założonych przeze mnie tematach ? Najwięcej się zawsze wymądrzasz, a jeszcze ani razu nie pomogłeś. Dzięki.

Jakbym uznał twoje pytanie za niebanalne albo byś chociaż umiał czytać moje odpowiedzi to bym tobie pomógł. No ale ba, jak chciałeś czytać cały plik i powiedziałem żebyś używał komponentu to co zrobiłeś? Końcem końców i tak używasz komponentu którego nie umiesz użyć.
Tak możesz prosić.

@-123oho: nawet jeżeli dobrze prawisz, nie każdy ma takie "poczucie humoru" i jest to z deka bezsensowne spamowanie w temacie.

Jeżeli ktoś ma takie "poczucie humoru" to jak najbardziej ma. IMO lepsze takie spamowanie niż szukanie za niego informacji o budowie plików PNG czy komponentu jak ty to robisz. To że Ty znaleźć umiesz wiemy, ale czy on googla nie ma? No on ma, tylko jest zbyt mądry aby zapytać go zanim zada pytanie na forum, bo mu się wydaje że na forum siedzą twórcy formatu PNG! Cytując klasyka 'Fuck google, ask me!'. A to traci na tym podwójnie bo oducza się myślenia i nie dowie się tak dużo jak z dokumentacji nikogo nie obchodzi.
Drogi pytaczu, jeżeli nie chcesz żebym się do ciebie czepiał to odrób pracę domową i zanim zapytasz poszukaj w dokumentacji i googlu czy twoje pytanie nie jest już gdzieś dobrze opisane. Zyskasz na tym potrójnie. A jeżeli szukałeś to pokaż nam to pokazując dlaczego poszczególne dokumentacje nie opisują twojego problemu.
Jeżeli szukasz miejsca od którego możesz zacząć szukanie to polecę www.google.pl w które możesz wpisać np. nazwę komponentu żeby znaleźć jego opis użycia i dokumentację.

0

Format PNG

Grafika

PNG nie jest obciążony patentami. Obsługuje stopniowaną przezroczystość (tzw. kanał alfa) oraz 48-bitową głębię kolorów czyli 16 bitów na kanał koloru. Dzięki temu można zapisać bezstratnie dowolne grafiki RGB (a nawet RGBA, czyli RGB+Alfa, do 64 bitów na piksel). Obsługuje też osadzone profile kolorów ICC, ICM i dane EXIF[1].

RGB

Zapis koloru jako RGB często stosuje się w informatyce (np. palety barw w plikach graficznych, w plikach html). Najczęściej stosowany jest 24-bitowy zapis kolorów (po 8 bitów na każdą z barw składowych), w którym każda z barw jest zapisana przy pomocy składowych, które przyjmują wartość z zakresu 0-255. W modelu RGB wartość 0 wszystkich składowych daje kolor czarny, natomiast 255 - kolor biały. W rzadszych przypadkach stosuje się model, w którym przypada po 12 lub 16 bitów na każdą ze składowych, co daje dużo większe możliwości przy manipulowaniu kolorem.

RGBA

Podstawowe informacje

Ten model czasami jest traktowany jako osobny, jednak w rzeczywistości jest to tradycyjny model RGB, poszerzony o dodatkowe informacje.

Kanał alfa

Kanał alfa normalnie jest używany jako odpowiednik współczynnika pochłaniania światła. Gdy kanał alfa skojarzony z danym pikselem ma wartość 0%, to taki piksel staje się całkowicie przezroczysty (czyli przybiera kolor tła pod nim - w rezultacie wydaje się, że nie widzimy go). Natomiast, gdy wartość zapisana we współczynniku alfa wyniesie α=100%, piksel będzie całkowicie widoczny (jak w zwykłym obrazie cyfrowym bez kanału alfa). Istnieje też możliwość nadania współczynnikowi alfa wartości pośrednich - między α=0 a α=100%. Takie wartości umożliwiają pikselom "prześwit" tła, na które zostały nałożone (pikselom nadaje się efekt półprzezroczystości). Taki efekt nie byłby możliwy we współczynniku binarnym - przyjmującym tylko dwie wartości - gdyż wtedy możliwe byłoby tylko tworzenie pikseli w pełni przezroczystych lub w pełni nieprzezroczystych (odpowiednio α=0%, oraz α=100%). Wprowadzenie współczynnika alfa pozwala w łatwy sposób manipulować obrazami i łączyć je ze sobą, jednocześnie zachowując efekty wzrokowe, znane z życia codziennego. Wartości kanału alfa mogą być wyrażane procentowo, jako liczby całkowite (najczęściej z przedziału od 0 do 255), lub liczby rzeczywiste (z przedziału od 0 do 1). Tak samo wyrażać można współczynniki RGB.

ARGB

Czasami spotyka się oznaczenie ARGB. Jest ono tożsame z RGBA, jednak kolejność współczynników jest odmienna (alfa jest pierwszym współczynnikiem). Jedną z firm, która użyła takie oznaczenie standardu w swoich produktach, jest Macromedia.


Odpowiedź jest jedna - wystarczyło poszukać; Najpierw jednak trzeba taki plik zdekodować by móc odczytać poszczególne piksele - kompresja daje w dupę; Wszystko za Ciebie wykona kontrolka - naucz się jedynie odczytywać z niej wartości;

0

Zrobiłem to w ten sposób i działa. Dzięki wielkie tym którzy pomogli.

procedure TBRDFConv.btnDodajClick(Sender: TObject);


var

tabByte1 : pbytearray  ;
tabByte2 : pbytearray ;
i, j  : integer;
width :integer;
height : integer ;
x, y , z :integer ;
R1, G1, B1 : double;
R , G , B : word;
TF : TextFile;
s:string;

begin
if render.ZliczajObrazy = render.AngleofIncidence then
MessageBox(Handle, 'Próbujesz wczytać większą ilość obrazów niż zadeklarowałeś.'
            + #10 +'Zadeklaruj większą liczbę obrazów', 'WRONG!', MB_OK or MB_ICONERROR)
else
begin;
  inc(render.ZliczajObrazy);
  Width := PNG.Width;
  Height := PNG.Height;
  if(render.ZliczajObrazy)=1 then
  begin
    setlength(Render.Obraz,render.AngleofIncidence,(Width-1),(Height));
  end;
  for y := 0 to (Height-2) do
  begin
    i := 0;
    tabByte1 := PNG.Scanline[y];
    tabByte2 := PNG.Extrascanline[y] ;
    for x := 0 to ((Width*3)-1) do
    begin
      inc(i);
      if i= 1 then
      begin
        R := TabByte2[x];
        R := R+(TabByte1[x]*(256));

      end;
      if i = 2 then
      begin
        G := TabByte2[x];
        G := G+(TabByte1[x]*(256));
      end;
      if i=3 then
      begin
        B := TabByte2[x];
        B := B+(TabByte1[x]*(256));
        i := 0;
        z := x div 3 ;
        R1:=0.21*R;
        G1:=0.71*G;
        B1:=0.07*B;
        R:=Round(R1);
        G:=Round(G1);
        B:=Round(B1);
        Render.Obraz[render.ZliczajObrazy-1][y][z] := R+G+B;
      end;

    end;
  end;

memo1.Lines.Add('Obraz nr. '+inttostr(render.ZliczajObrazy)) ;
memo1.Lines.Add('Ścieżka : ' +OpenDialog1.FileName);
memo1.Lines.Add('Rozdzielczośc : ' +inttostr(Width) +' x ' +inttostr(Height));
memo1.Lines.Add(' ');

end;

end; 

1 użytkowników online, w tym zalogowanych: 0, gości: 1