Ho seguito il (saggio) consiglio di MItaly ed ho scritto un codice che copia un rectangle da una bitmap gigantesca b1 in una seconda bitmap b2 in memoria. Tutto funziona bene MA ad una condizione: il Width della b1 DEVE essere un multiplo di 4, altrimenti succede quello che potete osservare nel test1 allegato. Allora ho fatto uno studio sull'head del file b1 prima e dopo aver tolto una colonna e quindi portare il Width di b1 da un valore multiplo di 4 ad un valore che non è multiplo di 4 (test2 allegato). Praticamente non cambia nulla di clamoroso se non il valore Width al byte n.18 che il mio codice tra l'altro legge bene e (stranamente) non cambia la dimensione totale in byte dell'immagine (byte n. 34) anche se ho effettuato un crop. A cosa può essere dovuto quel disastro? Perchè sono costretto ad usare Width forzati a multipli di 4 quando esistono bitmap di ogni dimensione? Non credo di aver sbagliato la funzione del puntatore (int) Ptr al byte nel mio codice perchè intanto funziona con le bitmap che hanno un Width multiplo di 4 ed inoltre, prima e dopo il crop, l'offset da cui partono i dati pixel dell'immagine (byte n.10) non è cambiato. Qualche idea?
codice:
string path = "gabri.bmp";
Vector4 Data = GetData(path);
int Dim1 = (int)Data.X;
int Dim2 = (int)Data.Y;
int Bits = (int)Data.Z;
int Ofs = (int)Data.W;
byte[] a = GetAllByte(path);
int x0 = 300;
int y0 = 50;
int dimx = 200;
int dimy = 100;
Bitmap b2 = new Bitmap(dimx, dimy);
int Ptr=0, R, G, B;
for(int y=y0; y < y0 + dimy; y++)
for (int x = x0; x < x0 + dimx; x++)
{
Ptr = Ofs + (Bits / 8) * (x + Dim1 * (Dim2 - y - 1));
B = Convert.ToInt32(a[Ptr]);
G = Convert.ToInt32(a[Ptr+1]);
R = Convert.ToInt32(a[Ptr+2]);
b2.SetPixel(x - x0, y - y0, System.Drawing.Color.FromArgb(R, G, B));
}
float ratio = 500f / Dim1;
if (Dim2 * ratio > 540)
ratio = 540f / Dim2;
pictureBox1.Width = (int)(Dim1 * ratio);
pictureBox1.Height = (int)(Dim2 * ratio);
pictureBox1.Visible = true;
pictureBox1.Image = b2;
b2.Save("b2.bmp");
codice:
public static Vector4 GetData(string path)
{
FileStream x = File.Open(path, FileMode.OpenOrCreate);
x.Seek(0, SeekOrigin.Begin);
byte[] b = new byte[30];
x.Read(b, 0, b.Length);
x.Close();
int offset = Convert.ToInt32(b[10]);
int Dim1 = Convert.ToInt32(b[18]) + Convert.ToInt32(b[19]) * 256;
int Dim2 = Convert.ToInt32(b[22]) + Convert.ToInt32(b[23]) * 256;
int bits = Convert.ToInt32(b[28]);
return new Vector4(Dim1, Dim2, bits, offset);
}
codice:
public static byte[] GetAllByte(string path)
{
FileStream f = File.Open(path, FileMode.OpenOrCreate);
f.Seek(0, SeekOrigin.Begin);
byte[] a = new byte[f.Length];
f.Read(a, 0, a.Length);
f.Close();
return a;
}