
Vykreslení obrázku z byte array
Zdravím, snažím se vykreslit obrázek bmp, který načítám do byte array, ale nedaří se mi to. Potřeboval bych poradit co změnit, aby mi to fungovalo. Chtěl bych, aby to fungovalo jen pro černobílý bmp obrázek pro jednoduchost a chci to uvedeným způsobem pomocí setpixel (ano vím, že je to pomalé).
Díky.
Metodu pro vykreslení mám takto:
public Bitmap VykresliObrazekBMP(Stream stream)
{
BinaryReader reader = new BinaryReader(stream);
int range = (int)reader.BaseStream.Length;
Byte[] bytes = reader.ReadBytes(56);
List<byte> bytess = new List<byte>();
foreach(var bajt in bytes)
{
bytess.Add(bajt);
}
int width = 361;
int height = 338;
Bitmap bmp = new Bitmap(width, height);
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
if (bytess.ElementAt(x) == 0)
{
bmp.SetPixel(x, y, Color.Black);
}
}
}
return bmp;
}
Přečteš 56 bytů a z toho se snažíš vykreslit obrázek 361x338 pixelů?
List bytess je tam zcela zbytečně.
Místo ElementAt můžeš použít přímo indexer [].
A asi nechceš neustále používat index x, ale spíš něco jako y * width + x.
Právě nevím kolik těch bytů mám přečíst, tak tam sem tam střelím nějaké číslo, ale hodí to chybu, že už je to moc.
Vždyť v range máš délku toho streamu.
Ahaaa, už to nějaké pixely kreslí, ale nějak divně. Dal jsem tam ten vzorec od tebe.
No a jak máš ten obrázek uložený v poli? Po řádcích nebo po sloupcích?
Myslím, že ten BinaryReader to ukládá po řádcích. Jako už to nějaké pixely kreslí, ale není to tak, jak by to mělo být.
A není to tak prostě proto, že se snažíš nečernobílý obrázek vykreslit černobíle?
Ne ne, dávám tam normálně černobílé bmp (klikatá čára nakreslená a uložená v malování jako bmp černobílý rastr).
No a víš o tom, že BMP obsahuje i nějakou hlavičku? A taky že když uložíš opravdu černobílý obrázek, tak v jednom bytu máš 8 pixelů?
To vím a s tím si právě nevím rady jak to tam realizovat.
Nastuduješ si strukturu BMP souboru, abys věděl, kolik toho máš přeskočit.
No a zbytek si převedeš na BitArray a pak už dál pracuješ obdobně jako teď.
No a k tomu doufej, že jsi to neuložil s nějakou kompresí.
Tak jsem to trochu upravil a pořád nejde.
No a jsi si opravdu jistý, že je ten BMP v takovém formátu, jaký očekáváš?
Jinak podmínka:
se dá prostě napsat jako:
Ano, jsem. Ale program padá kvůli vyjímce, že někde bere hodnotu null.
Tak to už je detail, spíš je oříšek to rozchodit.
Někde, kde? Pokud chceš poradit, musíš poskytovat veškeré informace. Zatím to z tebe leze jako z chlupaté deky.
Padá to na tom řádku Array.Copy(bytes, 0, newBytes, 54, range - 54);
Když to nahradím newBytes = bytes.Skip(54).Take(range - 54).ToArray();
Tak mi to začne kreslit toto:
Černá = false, ty to máš obráceně.
Jen tak pro zajímavost, jaké má ten obrázek rozměry v pixelech a jakou má ten soubor velikost v bytech?
Jo, na to jsem teď taky došel.
Obrázek má rozměry 1403 x 693 pixelů a velikost 122 030 bytů.
A vážně se to snažíš vykreslit do bitmapy 361x338?
Nejspíš na tom záležet nebude, protože i když mám obrázek stejné velikosti, tak to padá na vykreslování.
A jsme zase u toho. Co přesně znamená, že to padá? A samozřejmě na tom záleží sakra hodně.
Padá to na podmínce if (bity[y * width + x] == false) a píše to:
"An unhandled exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll
Additional information: Index je mimo rozsah. Index musí být nezáporný a musí být menší než velikost kolekce."
Takže v tom poli máš evidentně míň prvků, než očekáváš.
Vždyť by to mělo být od 54, protože 14 bytů je hlavička + 40 bytů jsou informace o souboru, ne?
Podle tohohle: https://en.wikipedia.org/wiki/BMP_file_format
to zdaleka není tak jednoduché.
Právě proto se ptám zkušených.
Schopnost přečíst dokumentaci nijak nesouvisí se zkušeností. To za tebe nikdo neudělá.