RGB565 to bmb/jpg/png/cos normalnego :/

0

Tak jak w temacie, potrzebuję w swoim programie otworzyć i wyświetlić obraz zapisany w formacie RGB565, a potem jeżeli użytkownik sobie zażyczy to zapisać go do jakiegoś typowego pliku graficznego pod windows.
Dodam że plik może być różnego rozmiaru, ale raczej nigdy nie przekracza 800x600.

Szukałem na ten temat na forum, lecz wyszukiwarka milczy.
Google natomiast nie mówi do mnie w ojczystym języku, jakieś wyniki w c++ czy c# tylko :/

Czy ktoś może mi z tym pomóc?

0

Utwórz obiekt TBitmap, dobierz się do jego pikseli (poprzez ScanLine, nie używaj Pixels[]), i przekształć bitmapę 565 na 888 za pomoca operacji bitowych. Potem zapisz jak tam chcesz.

0
Azarien napisał(a)

Utwórz obiekt TBitmap, dobierz się do jego pikseli (poprzez ScanLine, nie używaj Pixels[]), i przekształć bitmapę 565 na 888 za pomoca operacji bitowych. Potem zapisz jak tam chcesz.

Dzięki za odpowiedź!

Wiedziałem że jakoś tak trzeba to zrobić, ale szczerze mówiąc to nie umiem.
Może kawałek jakiegoś przykładu? Proszę!
Resztę jakoś sam zduszę.

0

bitmapa 565 ma tak ułożone bity

 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
|  R E D      |  G R E E N      |  B L U E     |

trzeba odczytać WORD, wziąć z niego pierwsze 5 bitów i zapisać do byte jako blue, potem kolejne 6 bitów jako green i kolejne 5 bitów jako red

0
Misiekd napisał(a)

bitmapa 565 ma tak ułożone bity

 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
|  R E D      |  G R E E N      |  B L U E     |

trzeba odczytać WORD, wziąć z niego pierwsze 5 bitów i zapisać do byte jako blue, potem kolejne 6 bitów jako green i kolejne 5 bitów jako red

Zara coś z tym powalczę, dzięki :)
btw kolega wyżej pisał żeby nie robić pixelami, czy to nie będzie bardzo wolne?

// edit

jak poznam że zaczyna się nowa linia pixeli? bo rozmiar obrazka może być różny.

0

potraktuj bitmapę 565 jako tablicę

0

Ok, już wiem jak otworzyć ten plik i pociachać do na wordy. Ale nie wiem jak z tego worda zrobić pixel :/
Sorry nie gryźcie ;)

0

http://4programmers.net/Delphi/Operacje_liczbowe/Obliczenia (operacje logiczne: bitowe), to powinno Ci wystarczyc :) And w tademie z shl'em spokojnie dadza rade.

0
cyriel napisał(a)

http://4programmers.net/Delphi/Operacje_liczbowe/Obliczenia (operacje logiczne: bitowe), to powinno Ci wystarczyc :) And w tademie z shl'em spokojnie dadza rade.

kurcze, zabiło mnie to :( to jest czarna magia dla mnie.
pomęczę to, spróbuje to zrozumieć jakoś :/

ale gdyby ktoś się nudził, miał tę godzinkę wolnego czasu i naskrobał by mi jakiś przykład był bym niezmiernie dźwięczny!
ale nie tylko ja! również tysiące osób korzystających z mojego darmowego programu, to ma być nowa funkcja do niego.

jak coś to pewnie prędzej czy później to rozgryzę, ale stracę mnóstwo cennego czasu na to.

pozdrawiam!

0
cimak napisał(a)

zerknij na to:
http://www.eioba.pl/a2160/operacje_logiczne_na_bitach

kurcze coś to nie do końca kumam, naskrobałem jakąś prowizoryczną prockę i ...
wyświetla piękny czarny prostokąt :)

procedure TForm1.Button1Click(Sender: TObject);
var
  pixel, x, y: word;
  r,g,b: byte;
  plik: File;
begin
  AssignFile(plik, 'c:\test');
  Reset(plik, 1);
  for x := 1 to 320 do begin
    for y := 1 to 480 do begin
      BlockRead(plik, pixel, SizeOf(pixel));
      r := r and pixel;
      g := g and (pixel shl 5);
      b := b and (pixel shl 6);
      canvas.Pixels[x,y] := rgb(r,g,b);
    end;
  end;
  CloseFile(plik);
end;

btw wolne to strasznie :/

Wie ktoś co trzeba poprawić żeby działało???

0

Panowie!!! Częściowy sukces!!!!

Zmodyfikowałem nieco kodzik:

procedure TForm1.Button1Click(Sender: TObject);
var
  pixel, x, y: word;
  r,g,b: byte;
  plik: File;
begin
  AssignFile(plik, 'c:\test');
  Reset(plik, 1);
  for x := 1 to 480 do begin
    for y := 1 to 320 do begin
      BlockRead(plik, pixel, SizeOf(pixel));
      r := 255;
      g := 255;
      b := 255;
      r := r and pixel;
      g := g and (pixel shl 5);
      b := b and (pixel shl 6);
      canvas.Pixels[y,x] := rgb(r,g,b);
    end;
  end;
  CloseFile(plik);
end;

efektem czego jest takie coś:
user image

Co zrobiłem źle że te kolory tak wyglądają??? :/

0

b := b and (pixel shl 6); zamien na b := b and (pixel shl 11); i powinno byc dobrze. I wrzuc tutaj troche mniejszy ten obrazek albo daj tylko link, bo ten to troche przegiecie jest.
Co do szybkosci to Azarien Ci juz napisal co musisz zrobic, wiec nie ma sensu tego powtarzac.

0
cyriel napisał(a)

b := b and (pixel shl 6); zamien na b := b and (pixel shl 11); i powinno byc dobrze. I wrzuc tutaj troche mniejszy ten obrazek albo daj tylko link, bo ten to troche przegiecie jest.
Co do szybkosci to Azarien Ci juz napisal co musisz zrobic, wiec nie ma sensu tego powtarzac.

jak dam wiecej niz shl 8 to komplitator nie puszcza, i chyba normalne to jest mi sie wydaje :/

Constant expression violates subrange bounds

0
      r := 255;
      g := 255;
      b := 255;
      r := r and pixel;
      g := g and (pixel shl 5);
      b := b and (pixel shl 6);

zamien na

      r := 255;
      g := 255;
      b := 255;
      r := r and pixel;
      pixel:=pixel shl 5;
      g := g and pixel;
      pixel:=pixel shl 6;
      b := b and pixel;
0
cyriel napisał(a)
      r := 255;
      g := 255;
      b := 255;
      r := r and pixel;
      g := g and (pixel shl 5);
      b := b and (pixel shl 6);

zamien na

      r := 255;
      g := 255;
      b := 255;
      r := r and pixel;
      pixel:=pixel shl 5;
      g := g and pixel;
      pixel:=pixel shl 6;
      b := b and pixel;

zmieniła się nieco gama kolorów, ale efekt podobny :/
user image

0

wrzuc gdzies oryginalny plik bmp565 bo sam musze pocwiczyc operacje binarne ;]

0
cimak napisał(a)

wrzuc gdzies oryginalny plik bmp565 bo sam musze pocwiczyc operacje binarne ;]

proszę: http://androidcommander.kriev.com/G1Screenshot_RGB565

dzięki wielkie za chęć pomocy :)

0

Nowa wersja ;P

 r := 255;
      g := 255;
      b := 255;
      b := b and pixel;
      pixel:=pixel shl 5;
      g := g and pixel;
      pixel:=pixel shl 6;
      r := r and pixel;
0

Wydaje mi się, że szybiej będzie, jeżeli odczytasz plik raz, a następne operacje będziesz wykonywać z pamięci. W każdym razie będzie to lepsze nic 154 tys operacji odczytu po word.

Zastanawiam się też dlaczego inicjalizujesz zmienne r,g,b wartoscią 255 zamiast 0 i operacja OR

0
cyriel napisał(a)

Nowa wersja ;P

 r := 255;
      g := 255;
      b := 255;
      b := b and pixel;
      pixel:=pixel shl 5;
      g := g and pixel;
      pixel:=pixel shl 6;
      r := r and pixel;

coraz ciekawiej ;-P

user image

toyman napisał(a)

Wydaje mi się, że szybiej będzie, jeżeli odczytasz plik raz, a następne operacje będziesz wykonywać z pamięci. W każdym razie będzie to lepsze nic 154 tys operacji odczytu po word.

Zastanawiam się też dlaczego inicjalizujesz zmienne r,g,b wartoscią 255 zamiast 0 i operacja OR

na razie chce to uruchomić po prostu, wydajnością zajmę się potem ;) ale dzięki :)

0

wiesz co, ten plik ktory umiesciles na serwerze... albo jest rabniety albo ja mam cos inaczej na kompie.
mam ten sam kod co Ty i na obrazku sa miejsca "zje*ane"... nie wiem czego to wina...
ale zerknij na to i powiedz jakie efekty daje:

       r:=pixel shr 8;
       g:=pixel shr 3;
       b:=pixel shl 3;
0
cimak napisał(a)

wiesz co, ten plik ktory umiesciles na serwerze... albo jest rabniety albo ja mam cos inaczej na kompie.
mam ten sam kod co Ty i na obrazku sa miejsca "zje*ane"... nie wiem czego to wina...
ale zerknij na to i powiedz jakie efekty daje:

       r:=pixel shr 8;
       g:=pixel shr 3;
       b:=pixel shl 3;

user image

działą pięknie teraz :) dziękuję zajebiście :-)

teraz muszę popracować na przyspieszeniem tego, poczytam coś o scanline i się pobawię. ale to jutro, już późno.

jak by co to jeszcze o coś mogę spytać jutro ;)

raz jeszcze dzięki! pozdrawiam!

0

zastanawia mnie jeszcze jak wyciagnac z pliku rozmiary bitmapy? da sie ilosc pixeli ale co z proporcjami?
a tu szybsze na scanline (nudzilo mi sie w nocy):

procedure TForm1.Button1Click(Sender: TObject);
var
  x,y: integer;
  pixel:Word;
  plik: File;
  bmp:TBitmap;
  row:pByteArray;
begin
 AssignFile(plik, 'c:\RGB565');
 Reset(plik, 1);

 bmp:=TBitmap.Create;
 bmp.PixelFormat:=pf24bit;

 bmp.Width:=320;
 bmp.Height:=480;

 for y:=0 to bmp.Height-1 do
     begin
      row:=bmp.ScanLine[y];
      x:=0;
      while x<bmp.Width*3 do
            begin
              BlockRead(plik, pixel, SizeOf(pixel));
              row[x+2]:=pixel shr 8;//R
              row[x+1]:=pixel shr 3;//G
              row[x]  :=pixel shl 3;//B
              x:=x+3;;
            end;
     end;

 image1.Picture.Bitmap:=bmp;
 bmp.Free;

 CloseFile(plik);
end;
0
cimak napisał(a)

zastanawia mnie jeszcze jak wyciagnac z pliku rozmiary bitmapy? da sie ilosc pixeli ale co z proporcjami?
a tu szybsze na scanline (nudzilo mi sie w nocy):

procedure TForm1.Button1Click(Sender: TObject);
var
  x,y: integer;
  pixel:Word;
  plik: File;
  bmp:TBitmap;
  row:pByteArray;
begin
 AssignFile(plik, 'c:\RGB565');
 Reset(plik, 1);

 bmp:=TBitmap.Create;
 bmp.PixelFormat:=pf24bit;

 bmp.Width:=320;
 bmp.Height:=480;

 for y:=0 to bmp.Height-1 do
     begin
      row:=bmp.ScanLine[y];
      x:=0;
      while x<bmp.Width*3 do
            begin
              BlockRead(plik, pixel, SizeOf(pixel));
              row[x+2]:=pixel shr 8;//R
              row[x+1]:=pixel shr 3;//G
              row[x]  :=pixel shl 3;//B
              x:=x+3;;
            end;
     end;

 image1.Picture.Bitmap:=bmp;
 bmp.Free;

 CloseFile(plik);
end;

wow! jesteś bogiem, ale wytestuję już juro (prawie śpie ;-P )

jak byś kiedyś wpadł do UK to zapraszam do Leeds! postawie ci taką kolejkę w barze że z niego nie wyjdziesz [browar]

// edit

jeszcze to na szybko wytestowałem, działa super mega szybko!!! dzięki!!! :)

0

hehe, ok, jak cos to dam znac ;]
dobranoc

0

OK, kodzik działa spoko, nawet całkiem szybko. Udało mi się nawet zrobić podgląd pulpitu mojego telefonu na żywo :)

Jednak mam dwa problemy jeszcze do rozwiązania :/

Pierwszy to wspomniany wcześniej rozmiar obrazu, może idzie to jakoś z pliku wyliczyć? Bo pÓÓÓÓki co założyłem że obraz ma 480x320, taką rozdzielczość ma mój telefon więc jest spoko. Ale niestety inne modele telefonów (działających z moim programem), mogą mieć inną rozdzielczość (np, 320x240 lub 800x480). Zobaczę jeszcze, bo może jestem w stanie te info wyciągnąć z fona zanim pobiorę screenshot, muszę poszperać ;)

Drugi problem to widok Landscape, po prostu tel ma żyroskop i wyświetlacz można przekręcić do orientacji poziomej. Przykłady:

Tak wygląda normalnie:
user image

Tak powinno wyglądać w Landscape:
user image

Aktualnie Landscape wygląda tak:
user image

A po pewnych próbach wyszło mi tak ;-P :
user image

Generalnie to przekręcić obraz można by po odczytaniu go, jednak to zbędna dodatkowa operacja, która znacznie spowolni działanie podczas użycia podglądu Live (i tak jest wolny jak na live :/), dlatego chcę to od razu rysować obrócone.
Moja próba nie miała prawa powodzenia, jako że zamieniłem jedynie wartości width z height ;) Żeby to działało jak trzeba, należało by przerobić ten kodzik, jednak nie bardzo jakoś se to ułożyć w głowie, jak by to miało być. Na logikę to przydało by mi się img.ScanColumn ;-P , ale nie ma niestety.

Czy podpowiedział by mi ktoś jak przerobić te procke? Nie wiem jak to przepisać przez tego scaline :/

0

kolejne pixele sa zapisane w takiej a nie innej kolejnosci
chyba najwygodniej byloby zrobic tablice i wrzucic do niej wszystkie r,g,b
a dopiero potem z tej tablicy tworzyc plik - bylo by to o tyle latwe ze masz dostep do dowolnego pixela a nie tylko do nastepnego.

0
znow_ja napisał(a)

kolejne pixele sa zapisane w takiej a nie innej kolejnosci
chyba najwygodniej byloby zrobic tablice i wrzucic do niej wszystkie r,g,b
a dopiero potem z tej tablicy tworzyc plik - bylo by to o tyle latwe ze masz dostep do dowolnego pixela a nie tylko do nastepnego.

ale wtedy wrócę do początku! wcześniej bawiłem się po pixelu bez scannline. Obracać mogłem dowolnie, nawet odbicie lustrzane itp. ale niestety to było znacznie, znacznie... , znacznie wolniejsze :/

0

wiem, zle mnie zrozumiales.
chodzi o to zeby nie czytac bezposrednio z pliku, tylko zaladowac caly plik do tablicy a potem w scanline korzystac z tablicy.

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