Timage 16 bitowy PNG

0

Hej. Posiadam kompilator Lazarus (chyba najnowszy) . Próbuje wczytać obraz 16bitowy do komponentu Timage. Coś mi sie wyświetla ale na pewno nie jest to obraz jaki ładuje. Tutaj zamieszczam kod :

var
 
 PNG: TPortableNetworkGraphic;
 BMP: TBitmap;


implementation

{$R *.lfm}



procedure Tladuj.btnWczytajClick(Sender: TObject);
var
    s: string;
    TF : TextFile;



begin

      OpenDialog1.Execute ;
      s:=OpenDialog1.Filename;
      s:=Utf8ToAnsi(s);
      PNG := TPortableNetworkGraphic.Create;
      BMP := TBitmap.Create;
      PNG.LoadFromFile(s);
      BMP.Assign(PNG);
      ImgPodglad.Picture.bitmap:= BMP;
    



end;          

Proszę o jakieś wskazówki co może być nie tak .

2

Posiadam kompilator Lazarus (chyba najnowszy)

Nie ma to jak sprawdzone informacje. Aż tak ciężko zobaczyć albo po prostu podać co to za wersja? Wiedziałem.

Próbuje wczytać obraz 16bitowy do komponentu Timage. Coś mi sie wyświetla ale na pewno nie jest to obraz jaki ładuje.

Mógłbyś podać też obraz.

s:=Utf8ToAnsi(s);

Bo?

PNG := TPortableNetworkGraphic.Create;
      BMP := TBitmap.Create;
      PNG.LoadFromFile(s);
      BMP.Assign(PNG);

Bo?

ImgPodglad.Picture.bitmap:= BMP;

Bo?

I gdzie jest zwalnianie?

Proszę o jakieś wskazówki co może być nie tak .

Nie tak są te kody które oznaczyłem komentarzami 'Bo?'. Załaduj ten obraz po ludzku poprzez ImgPodlad.Picture.LoadFromFile().

2

Zanim dostanę masę minusów za wprowadzanie w błąd chciałbym poprawić tenże błąd. Oczywiście nie miało być ImgPodlad.Picture.LoadFromFile() tylko ImgPodglad.Picture.LoadFromFile(). I tak wiem że dostanę masę minusów.

0

Wersja kompilatora to 1.0 z 28.08.2012.
Poprawiłem kod w ten sposób :


begin

      OpenDialog1.Execute ;
      s:=OpenDialog1.Filename;
      s:=Utf8ToAnsi(s);
      PNG := TPortableNetworkGraphic.Create;
    //  BMP := TBitmap.Create;
    //  PNG.LoadFromFile(s);
    //  BMP.Assign(PNG);
      ImgPodglad.Picture.loadfromfile(s);
end; 

 

ale w dalszym ciagu wyświetlają mi się śmieci

a to :

 

      OpenDialog1.Execute ;
      s:=OpenDialog1.Filename;
      s:=Utf8ToAnsi(s);
    


          

dlatego, że nie mogłem wczytywać plików w których nazwie były polskie litery. To rozwiązało problem

a obraz który wczytuje to ten : http://www.bundysoft.com/L3DT/gallery/dump/2009_sept_17/png16_example.png

0

Wersja kompilatora to 1.0 z 28.08.2012.

Tak, najnowsza. Tylko że to nie jest kompilator. Kompilatorem jest FPC 2.6.0. Lazarus jest środowiskiem, za samą kompilację odpowiada FPC.

 OpenDialog1.Execute ;
      s:=OpenDialog1.Filename;
      s:=Utf8ToAnsi(s);
      PNG := TPortableNetworkGraphic.Create;
    //  BMP := TBitmap.Create;
    //  PNG.LoadFromFile(s);
    //  BMP.Assign(PNG);
      ImgPodglad.Picture.loadfromfile(s);

Skoro już tego nie używasz to po co tworzysz PNG? Wywal to też. Lazarus to nie Delphi, nie potrzebujesz bodaj żadnych trików żeby ładować JPEG/PNG.

dlatego, że nie mogłem wczytywać plików w których nazwie były polskie litery. To rozwiązało problem

Okej.

Ten problem dotyczy błędu w FPC 2.6.0 który został naprawiony w wersji 2.7.1 r22141 . Tutaj jest link do dokumentu na ten temat http://bugs.freepascal.org/view.php?id=19209 . Jeżeli bardzo tobie zależy na naprawie tego błędu to możesz spróbować włączyć patch do 2.6.0 albo przekompilować FPC i Lazarusa. Jeżeli chcesz to tu masz co nieco o tym (ale generalnie to robota dla osób które się znają na makefile etc.): http://wiki.freepascal.org/Getting_Lazarus

0

W jaki sposób mógłbym włączyć tego patcha ? Rozumiem że jest to dużo łatwiejsze niż druga z opcji którą zaproponowałeś ?

0
artender napisał(a):

W jaki sposób mógłbym włączyć tego patcha ? Rozumiem że jest to dużo łatwiejsze niż druga z opcji którą zaproponowałeś ?

Niekoniecznie, bo o ile FPC w odpowiedniej wersji masz już pewnie to nie jest on przystosowany zbyt do rekompilacji. Patcha możesz włączyć używając jakiegoś toolkita do tego, jest on do pobrania na stronie o tym błędzie. Właściwie to o ile nie jest on dużo to możesz go ręcznie wkleić. Ale wtedy jeszcze musisz przekompilować FPC z tym patchem a Lazarusa też by się przydało. Osobiście uważam za łatwiejszą opcję z budowaniem Lazarusa ze źródeł.

0

Ajj pospieszyłem się z ekscytacją... O ile zainstalowanie lazarusa w wersji 1.1 z FPC 2.7.1 pomogło w przypadku wyswietlenia obrazu podanego powyżej to w przypadku obrazu PNG z 48 bitową głębią nie... Obraz cały czarny...

0

Znalazłem to : http://bugs.freepascal.org/view.php?id=20361 . Mój problem .. W ostatnim poście na tej stronie napisane jest że działa z jakąś wersją. Mógłby mi ktoś pomóc znaleźć tą wersję . Gogluje gogluje i nic sie do posuwam do przodu ..

0
-123oho napisał(a):

Skoro już tego nie używasz to po co tworzysz PNG? Wywal to też. Lazarus to nie Delphi, nie potrzebujesz bodaj żadnych trików żeby ładować JPEG/PNG.

No tak bo Delphi zatrzymało się na wersji 7. W nowszych Delphi też nie trzeba cudów aby załadować PNG (jpg to samo)

Image1.Picture.LoadFromFile('G:\ąćęłńóśźż\ąćęłńóśźż.png');

No chyba że trickiem jest dodanie do uses PNGImage (moduł wbudowany w Delphi)

0

Znalazłem jeszcze coś . Od biedy można przekonwertować plik PNG na bmp i ten drugi wyświetlić. Coś takiego :

procedure TForm1.Button1Click(Sender: TObject);
var
  image: TFPCustomImage;
  reader: TFPCustomImageReader;
  writer: TFPCustomImageWriter;
  AFileName, ADestFileName: string;
begin
  Image := TFPMemoryImage.Create(10, 10);
  Reader := TFPReaderPNG.Create;
  Writer := TFPWriterBMP.Create;

  AFileName := '.\30.png';
  ADestFileName := '.\4286.bmp';

  Image.LoadFromFile(AFileName, Reader);
  Image.SaveToFile(ADestFileName, Writer);
  Writer.Free;
  imagePodglad.Picture.LoadFromFile(ADestfilename);
  Reader.Free;
  Image.Free;
end; 

ale jak w tym przypadku użyć scanline i extrascanline ?

0

Znalazłem to : http://bugs.freepascal.org/view.php?id=20361 . Mój problem .. W ostatnim poście na tej stronie napisane jest że działa z jakąś wersją. Mógłby mi ktoś pomóc znaleźć tą wersję . Gogluje gogluje i nic sie do posuwam do przodu ..

Chodzi o rewizje 22141 którą możesz sobie pobrać z SVN. Nie wszystko jest w googlu, tak jak ten problem jeszcze nie jest rozwiązany. Możesz być pierwszy.

Ajj pospieszyłem się z ekscytacją... O ile zainstalowanie lazarusa w wersji 1.1 z FPC 2.7.1 pomogło w przypadku wyswietlenia obrazu podanego powyżej to w przypadku obrazu PNG z 48 bitową głębią nie... Obraz cały czarny...

Edytować postu nie można i dopisać? Nie, napiszmy kolejny!!!
Możesz sprawdzić czy wersja 1.0 działa z obrazami 48 bitowymi? Jeżeli tak to najprawdopodobniej naprawa tamtego błędu powoduje nowy błąd. Wersja 1.1 i 2.7.1 FPC to wersje testowe więc zawierają nie tylko nowe dodatki ale też potencjalnie nowe błędy których wersja stabilna zawiera mniej.
Jeżeli chcesz to możesz samemu sprawdzić co w kodzie jest nie tak i opublikować łatkę ale to wymaga już sporego nakładu pracy.

No tak bo Delphi zatrzymało się na wersji 7. W nowszych Delphi też nie trzeba cudów aby załadować PNG (jpg to samo)

Dla wielu osób Delphi rzeczywiście zatrzymało się na wersji 7. Już nie mówiąc o tym że przestały dla nich także istnieć alternatywy.

ale jak w tym przypadku użyć scanline i extrascanline ?

Może zamiast postując nam poszlaki (de facto problem który odpisałeś na początku jest rozwiązany) zapostuj co chcesz osiągnąć.

0

Chciałbym odczytać pixele z obrazu PNG . Wiem iż aby to zrobić z obrazu o 48 bitowej głębi należałoby użyć scanline i extrascanline.

0
artender napisał(a):

Chciałbym odczytać pixele z obrazu PNG .

Powtórzę raz jeszcze: Jaki jest twój cel. Nie ładujesz pliku żeby ładować plik. Nie odczytujesz pikseli żeby odczytywać piksele.

Wiem iż aby to zrobić z obrazu o 48 bitowej głębi należałoby użyć scanline i extrascanline.

Wczoraj mówiłeś o obrazie o 16 bitowej głębi. Szukasz metody dla każdego obrazu czy dla specjalnej głębi.

0

Szukam metody na na wyświetlenie obrazu (PNG w RGB - na kazdy kanał 16 bitów - razem 48 ) w komponencie i zapoznanie się z wartościami pixeli (wartości każdego z kanałów RGB) . Potrzebuje znajomość pikseli do swojej pracy dyplomowej . Później je będę przetwarzał już za pomocą innych algorytmów gdy już je będę miał w tablicy.

0

W zasadzie dalej nie napisałeś co i po co. Może ja wyjaśnię :D Co nieco pamiętam z poprzednich postów.

@artender używa pewnego programu do wygenerowania pewnych obrazów o wysokiej głębi kolorów. Ów program potrafi zapisywać takie obrazy w formacie PNG (BTW, są inne formaty dostępne w tej głębi?). Następnie chce przetwarzać oraz wyświetlać te obrazy w swojej aplikacji pisanej w Lazarusie.

Jeszcze się upewnię co do paru rzeczy:

  • potrzebujesz pełnej głębi w swoim programie czy wystarczy ci może 8bit na kanał?
  • czy rzeczywiście potrzebujesz wyświetlać te obrazy w swoim programie?

Może faktycznie użyć by jakiejś zewnętrznej biblioteki. Może libpng? Pracy będzie więcej, ale mus to mus...

0

Tak potrzebuje pełnej głębi oraz wyświetlenia obrazu . Wyświetlić obraz to już teraz dałbym radę konwertując obraz do bitmapy pozostaje tylko odczyt pikseli. Użyłbym libpng tylko nie widziałem żeby było dostępne na lazarusa. Próbowałem jakoś przekonwertować tą bibliotekę z delphi do lazarusa ale bez powodzenia. @adf88 Przejrzałeś mnie ;)

0

Szukam metody na na wyświetlenie obrazu (PNG w RGB - na kazdy kanał 16 bitów - razem 48 ) w komponencie i zapoznanie się z wartościami pixeli (wartości każdego z kanałów RGB) .

procedure TForm1.Button1Click(Sender: TObject);
  var
  fs:TFileStream;
  png:TFPReaderPNG;
  img:TFPCustomImage;
begin
  fs:=TFileStream.Create('x.png',fmOpenRead);
  png:=TFPReaderPNG.create;
  img:=png.ImageRead(fs,nil);
  writeln(img.Width,#32,img.Height);
  image1.Picture.Assign(img);
  fs.Free;
  png.Free;
  img.Free;
end;  

Poprzez IMG masz dostęp do 16bitowych wartości RGB.
Widzę że taktyka szukania w googlu i używaniu TBrain jest używana tylko przeze mnie.

Przy czym nadal nie wyjaśniłeś mi kiedy twój problem występuje, nie wiem kiedy działa, kiedy nie działa, co działa i co nie działa. Twierdzisz że pewne obrazy powodują że cały imidż jest czarny - pytam więc czy jest tak samo pod 1.0 i 1.1 . Pewnie w kodzie dekodującym piksele jest jakiś mały bug który się czasami ujawnia.

Może faktycznie użyć by jakiejś zewnętrznej biblioteki. Może libpng?

Można, ale wydaje mi się że fcl-image powinno dać radę po ew. fixie.

Wyświetlić obraz to już teraz dałbym radę konwertując obraz do bitmapy pozostaje tylko odczyt pikseli.

Przecież dałem ci wyświetlanie poprzez LoadFromFile który działa na PNG, jaki masz z tym problem?!

Wyjaśnij CO JEST OK, A CO NIE. Bo póki co to najpierw pierniczysz że działa potem że nie. Oczekuję dokładnego wyjaśnienia co było nie tak na 1.0 i co się zmieniło po przejściu na 1.1 . Wytłumacz co już jest zrobione i nie zawracaj mi tym głowy tylko powiedz co jeszcze chcesz wiedzieć. Pierniczysz masę rzeczy w których nikt już rozeznania nie ma...

Użyłbym libpng tylko nie widziałem żeby było dostępne na lazarusa.

Ot brakuje mu bibliotek do png na lazarusa... Eh, google too hard.

0

A więc tak . Pod 1.0 nie działa wyświetlanie PNG 16bit ani 48bit. Pod 1.1 działa wyświetlanie w Timage tylko PNG 16 bit (ja potrzebuje w głębi 48bit ). Jednak można to obejść w ten sposób :

procedure TForm1.Button1Click(Sender: TObject);
var
  image: TFPCustomImage;
  reader: TFPCustomImageReader;
  writer: TFPCustomImageWriter;
  AFileName, ADestFileName: string;
begin
  Image := TFPMemoryImage.Create(10, 10);
  Reader := TFPReaderPNG.Create;
  Writer := TFPWriterBMP.Create;
 
  AFileName := '.\30.png';
  ADestFileName := '.\4286.bmp';
 
  Image.LoadFromFile(AFileName, Reader);
  Image.SaveToFile(ADestFileName, Writer);
  Writer.Free;
  imagePodglad.Picture.LoadFromFile(ADestfilename);
  Reader.Free;
  Image.Free;
end;  

Za pomocą powyższego kodu jestem w stanie wyświetlić obraz 48bit png w komponencie Timage (a właściwie jego kopie przekonwertowaną na bitmape). Tak więc jedynym problemem jaki mi został to odczyt wartości pikseli (nie z bitmapy a z oryginalnego obrazu PNG o 48 bitowej głębi kolorów)

0

Pod 1.0 nie działa wyświetlanie PNG 16bit ani 48bit.

Przed chwilą mi wmawiałeś że 16bitowy PNG to to samo co 48 bitowy.
Wczoraj mówiłeś o obrazie o 16 bitowej głębi. Szukasz metody dla każdego obrazu czy dla specjalnej głębi. -> PNG w RGB - na kazdy kanał 16 bitów - razem 48?!?

Jednak można to obejść w ten sposób :

Zmartwię cię: To używa tej samej metody co TImage.Picture.LoadFrom* . Źle zbudowany lazarus?

Za pomocą powyższego kodu jestem w stanie wyświetlić obraz 48bit png w komponencie Timage

Możesz mi wytłumaczyć jak używając tego samego tylko na około wychodzi ci coś innego??? Najpewniej pierniczysz głupoty. Zobacz jeszcze moją metodę która bezpośrednio wywołuje prymitywy.

0

Cały czas chodzi mi o obraz o 48bitowej głebi koloru. Możliwe że wczoraj się pomyliłem i mówiąc 16bitowy chodziło mi o 16 bitów na kanał . I jeszcze raz piszę że wczytując obraz 48bitowy standardowo do komponentu Timage poprzez Timage.Picture.Loadfromfile komponent wyswietla cały czarny obraz zarówno pod 1.0 jak i pod 1.1. Aby wyświetlić go poprawnie użyłem kodu przytoczonego w powyższym poście który konwertuje PNG 48bit na Bitmape i wyświetla tą bitmapę. Czyli sprawę wyświetlania obrazu mam z głowy.

Jedyny problem to odczyt wartości pikseli. Nie mam pojęcia w jaki sposób to zrobić (**odczyt pikseli z PNG o 48bitowej głębi kolorów **) . W TFPreaderPNG nie widziałem funkcji scanline lub extrascanline.

0

Aby wyświetlić go poprawnie użyłem kodu przytoczonego w powyższym poście który konwertuje PNG 48bit na Bitmape i wyświetla tą bitmapę. Czyli sprawę wyświetlania obrazu mam z głowy.

Sprawdź mój kod?

Jedyny problem to odczyt wartości pikseli. Nie mam pojęcia w jaki sposób to zrobić (odczyt pikseli z PNG o 48bitowej głębi kolorów ) . W TFPreaderPNG nie widziałem funkcji scanline lub extrascanline.

Sprawdź mój kod?

I jeszcze raz piszę że wczytując obraz 48bitowy standardowo do komponentu Timage poprzez Timage.Picture.Loadfromfile komponent wyswietla cały czarny obraz zarówno pod 1.0 jak i pod 1.1.

Może to bug wyświetlania nie dekodowania. Ciężko mi powiedzieć jako że specjalistą od RTL ani kompilatora nie jestem.

0

@-123oho masz rację , obraz 48bitowy ładuje się bez problemów . Jednak w dalszym ciagu nie umiem sobie poradzić z odczytem wartości pixeli. Jakbys mi jeszcze pomógł z tym jakiej funkcji uŻyć do ich odczytu to bym był wdzięczny.

0

. Jednak w dalszym ciagu nie umiem sobie poradzić z odczytem wartości pixeli. Jakbys mi jeszcze pomógł z tym jakiej funkcji uŻyć do ich odczytu to bym był wdzięczny.

TFPCustomImage w googlu albo img.<Ctrl+Spacja> tak trudno użyć?
Bądź na tyle miły i pracuj sam zamiast oczekiwać że wszędzie cię za rączkę poprowadzę, zwłaszcza tam gdzie wszystko sprowadza się do czytania dokumentacji.

0

@-123oho . img.<Ctrl+Spacja - szukałem ale nie bardzo znalazłem jakąs funkcję wskazującą na to że to potrafi . Tak samo w googlu po wpisaniu TFPCustomeimage niczego nie znalazłem...

0

img.<Ctrl+Spacja - szukałem ale nie bardzo znalazłem jakąs funkcję wskazującą na to że to potrafi .

Eh, weź to wpisz w Lazarusa gdzieś gdzie jest img zdefiniowane i użyj tej kombinacji klawiszy...

Tak samo w googlu po wpisaniu TFPCustomeimage niczego nie znalazłem...

Tak to jest jak się nie wie jak się pisze Custom, czyż nie? Nie żartuj że nie ma bo pierwszy wynik to doc Lazarusa...

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