?
Als Anregung:
Untere Funktion verwendet Scanline um eine um 0, 90, 180 oder 270 Grad zu gedrehte Bitmap aus einem Bytearray zu erstellen. Ist aber nur nur für 8 Bit Farbtiefe geeignet (Byte*, Such mal nach RGBTRIPLE in der Hilfe). Da die Dateien, die ich einlesen muß, alle DIN A4, 600 dpi-JPEGs sind, sind sie recht groß (im Arbeitsspeicher). Deswegen waren Canvas-Zugriffe viel zu langsam und ich mußte Scanline verwenden. Die Bitmap wird dazu beim Laden erst in BitmapShow gelesen und dann in ein Bytearray im Arbeitsspeicher gelegt (ausgelesen über Scanline).
globale Variablen:
ymaxorg und xmaxorg sind int und geben die Größe des Originalbitmaps an
Imagedata ist ein Array aus Byte, in der Größe des Bitmaps. Dieses Array wird, beim Öffnen der Datei, mit den Original-Bitmappixeldaten gefüllt.
BitmapShow (Graphics::TBitmap) nimmt das auszugebende Bild auf
bmp_rotate gibt nur an, um wieviel Grad das Bild gedreht wird.
void __fastcall TFormJPEGViewer::RotateBitmap(void)
{
int ymaxrot;
int xmaxrot;
if (bmp_rotate == 2 || bmp_rotate == 0)
{
ymaxrot = ymaxorg;
xmaxrot = xmaxorg;
}
else
{
ymaxrot = xmaxorg;
xmaxrot = ymaxorg;
}
BitmapShow->Width = xmaxrot;
BitmapShow->Height = ymaxrot;
Byte* slRotated;
pImagedata = Imagedata;
if (bmp_rotate == 0) // 0° gedreht
{
for (int y = ymaxrot - 1; y >= 0; y--)
{
slRotated = (Byte*) BitmapShow->ScanLine[y];
for (int x = xmaxrot - 1; x >= 0; x--)
{
*slRotated = *pImagedata;
slRotated++;
pImagedata++;
}
}
}
if (bmp_rotate == 2) // 180° gedreht
{
for (int y = 0; y < ymaxrot; y++)
{
slRotated = (Byte*) BitmapShow->ScanLine[y];
slRotated += xmaxrot - 1;
for (int x = 0; x < xmaxrot; x++)
{
*slRotated = *pImagedata;
slRotated--;
pImagedata++;
}
}
}
if (bmp_rotate == 3) // 270° gedreht
{
for (int y = ymaxrot - 1; y >= 0; y--)
{
slRotated = (Byte*) BitmapShow->ScanLine[y];
slRotated += xmaxrot - 1;
for (int x = 0; x < xmaxrot; x++)
{
*slRotated = Imagedata[ymaxrot - 1 - y + (x * xmaxorg)];
slRotated--;
}
}
}
if (bmp_rotate == 1) // 90° gedreht
{
for (int y = 0; y < ymaxrot; y++)
{
slRotated = (Byte*) BitmapShow->ScanLine[y];
for (int x = 0; x < xmaxrot; x++)
{
*slRotated = Imagedata[y + (x * xmaxorg)];
slRotated++;
}
}
}
bmp_rotate_old = bmp_rotate;
}
Schau Dir mal den Abschnitt um 0° drehen an. Dort wird aus dem im Arbeitsspeicher hinterlegten Daten das Bitmap unverändert wieder hergestellt.
*slRotated = *pImagedata
Hiermit wird ein Byte aus dem Array in die Scanline geschrieben. Kannst also den Werte aus *pImagedata einlesen (ersetzt das Lesen von Canvas->Pixel[x][y]) umrechnen und ín *slRotated reischreiben (ersetzt das Schreiben von Canvas->Pixel[x][y]).
Ich kann Dir das Testprojekt, aus dem diese Funktion stammt am Montag mal zum Download bereitstellen, oder zumailen.