PictView - otáčení obrázku podle EXIF
PictView - otáčení obrázku podle EXIF
Jak už bylo několikrát uvedeno PictView je perfektní pro prohlížení fotek, ale jedna věc mi hrozně vadí. Neumí automaticky otáčet fotky podle údaje v EXIF (pokud jsou foceny na výšku). Nešlo by to doplnit?
-
- Plugin Developer
- Posts: 707
- Joined: 08 Dec 2005, 14:33
- Location: Prague, Czech Republic
- Contact:
Re: PictView - otáčení obrázku podle EXIF
Mame to v planu, diky za pripomenutiRoman wrote:Jak už bylo několikrát uvedeno PictView je perfektní pro prohlížení fotek, ale jedna věc mi hrozně vadí. Neumí automaticky otáčet fotky podle údaje v EXIF (pokud jsou foceny na výšku). Nešlo by to doplnit?

Tomu vašemu argumentu moc nerozumím
Podle mne jakákoliv bitmapová data lze v paměti reprezentovat dvourozměrným polem pixelů - jeho velikost znám z hlavičky souboru.
Pak už jen toto pole plním pixely obrázku buď po řádcích od shora dolů (v případě většiny formátů) nebo po řádcích od sdola nahoru (v případě většiny BMP souborů) nebo ho také můžu plnit po "datových řádcích" ale v obrázku otočeně po sloupcích zleva-doprava nebo z prava doleva.
v pseudo kódu otočení o -90° hned při načítnání:-> takto načítám data jak jdou do řádcích, ale plním je ve výsledném poli po sloupích. Jen je třeba napsat všechny možnosti otočení a ne jen tento jeden případ.

Podle mne jakákoliv bitmapová data lze v paměti reprezentovat dvourozměrným polem pixelů - jeho velikost znám z hlavičky souboru.
Pak už jen toto pole plním pixely obrázku buď po řádcích od shora dolů (v případě většiny formátů) nebo po řádcích od sdola nahoru (v případě většiny BMP souborů) nebo ho také můžu plnit po "datových řádcích" ale v obrázku otočeně po sloupcích zleva-doprava nebo z prava doleva.
v pseudo kódu otočení o -90° hned při načítnání:
Code: Select all
imgWidth = dataHeight;
imgHeight = dataWidth;
img = new RGB[imgWidth, imgHeight];
for (int dx; dx < dataWidth; dx++)
for (int dy; dy < dataHeight; dy++)
{
imgX = dy;
imgY = dataWidth - dx - 1;
img[imgX, imgY] = datasource.GetNextPixel();
}
Jo, přesně tak, jde mi o to, že při dekompresi můžu vzít celý řádek (nebo klidně větší blok) a ten plácnout na obrazovku. Aby tohle efektivní načtení bylo zachováno i pro simulovanou rotaci, muselo by se číst ze zdrojového souboru ne sekvenčně, ale na přeskáčku (po těch "sloupcích" jak jsem psal). Vy nicméně navrhujete nomální sekvenční čtení a zápis po jednom pixelu, v tom vidím ten problém - při vyrotování se musí postupovat načítáním po jednom pixelu (pokud to neudělá grafická karta při použití akcelerace, což myslím třeba při xBlt z GDI nedělá), a proto je to tak pomalé. První operace (nasypání bloku dat) má ve srovnání s tou druhou minimální časovou složitost, a vy navrhujete pouze tu pomalou druhou operaci provádět už jako součást prvního kroku, v tom žádné urychlení nevidím. Ale možná se v něčem pletu?
Last edited by Mem on 27 May 2006, 17:12, edited 1 time in total.
Netuším, jak to dělá PictView, a nejsem ani odborník na jednotlivé formáty, ale otáčet už při dekódování mi přijde neprůchozí.
Každý typ/formát má už svůj odladěný a lety prověřený algoritmus, který předpokládá nějak stavěné řádky a sloupce. Rozhodně to není plnění pole znak po znaku. Např. lzw komprese (.gif) využívá opakování a zpětné doplnění stejné sekvence - a je sakra rozdíl, jestli máte tu sekvenci v paměti reálně za sebou nebo ob šířku obrázku (x86 mají instrukce pro kopii bloku bytes za sebou a cache procesoru při přístupu do paměti je optimalizována na přímou sekvenci). Takže zde by bylo IMHO rychlejší (nebo přinejmenším stejně rychlé) obraz vytvořit klasicky a až pak otočit.
Takže zaměnit sloupce a řádky už při načítání by u některých formátů teoreticky šlo. Ale fakticky to znamená mít duplikovaný (resp. triplikovaný) algoritmus pro každý formát zvlášť, mnohdy úplně nově vyvíjený (z ohledem na rychlost) a ne vždy přinášející zrychlení oproti sekvenci dekóduj-otoč.
Každý typ/formát má už svůj odladěný a lety prověřený algoritmus, který předpokládá nějak stavěné řádky a sloupce. Rozhodně to není plnění pole znak po znaku. Např. lzw komprese (.gif) využívá opakování a zpětné doplnění stejné sekvence - a je sakra rozdíl, jestli máte tu sekvenci v paměti reálně za sebou nebo ob šířku obrázku (x86 mají instrukce pro kopii bloku bytes za sebou a cache procesoru při přístupu do paměti je optimalizována na přímou sekvenci). Takže zde by bylo IMHO rychlejší (nebo přinejmenším stejně rychlé) obraz vytvořit klasicky a až pak otočit.
Takže zaměnit sloupce a řádky už při načítání by u některých formátů teoreticky šlo. Ale fakticky to znamená mít duplikovaný (resp. triplikovaný) algoritmus pro každý formát zvlášť, mnohdy úplně nově vyvíjený (z ohledem na rychlost) a ne vždy přinášející zrychlení oproti sekvenci dekóduj-otoč.
Datalog: nee, zarevak to myslel tak, že obrázek se načte klasicky sekvenčně (viz ta metoda GetNextPixel), pouze se bude umisťovat do bufferu s obrázkem per pixel (i když pokud se ta obrazová data současně využívají při další dekomprimaci (viz to LZW*), tak by jiná reprezentace pole přinesla problém, to máte pravdu).
Spíš by stálo za to zvážit využití grafické akcelerace a třeba OGL nebo DX pro rotaci, i když tady samozřejmě vyvstává řada dalších problémů (velikosti textur, filtrování atd.).
P.S.: *I když pokud si dobře pamatuji, tak zrovna LZW by měl mít budovaný slovník mimo, fráze v dekódovaném textu využívá LZ77/78, stejně ale je možné, že tuhle kompresi nějaký formát také využívá
Spíš by stálo za to zvážit využití grafické akcelerace a třeba OGL nebo DX pro rotaci, i když tady samozřejmě vyvstává řada dalších problémů (velikosti textur, filtrování atd.).
P.S.: *I když pokud si dobře pamatuji, tak zrovna LZW by měl mít budovaný slovník mimo, fráze v dekódovaném textu využívá LZ77/78, stejně ale je možné, že tuhle kompresi nějaký formát také využívá
Mem: díky za ozřejmění, bude to tak jak říkáte.
* LZW: nakolik si pamatuji (málo
), LZW potřebuje vytvářet slovník pouze při kompresi, pro urychlení nalezení shodných úseků. Pro rozbalení stále stačí jedno sekvenční okno - nicméně je možné, že i to si dělá bokem a nevyužívá výstupních dat, záleží na implementaci.
EDIT: Tak mi to nedalo a trochu jsem brouzdal po netu a vypadá to, že LZW potřebuje slovník i při dekompresi. Njn, už je to dávno, paměť neslouží
. Omlouvám se za mystifikace.
* LZW: nakolik si pamatuji (málo

EDIT: Tak mi to nedalo a trochu jsem brouzdal po netu a vypadá to, že LZW potřebuje slovník i při dekompresi. Njn, už je to dávno, paměť neslouží

Jj, já mám ze školy přeci jen asi blíž, takže si rozdíl mezi LZ77 a LZW ještě celkem vybavuju, u LZW se kódují čísla frází ze slovníku, u LZx ta pozice v okénku jak píšeteDatalog wrote:EDIT: Tak mi to nedalo a trochu jsem brouzdal po netu a vypadá to, že LZW potřebuje slovník i při dekompresi. Njn, už je to dávno, paměť neslouží. Omlouvám se za mystifikace.