2016-04-18 20 views
0

Ich bin vor kurzem auschecken C für einen Freund Probleme mit ihm für die Schule. Da ich nur Java und C# gelernt habe, wäre es doch einfach. Aber momentan stecken wir darauf fest.C Bitmap: Rotation und Zoom

Ich habe ein Projekt lesen ein kleines BMP (512x512) Bild. Ich habe es geschafft, ein paar Farben zu ändern und sie zu drehen (sowohl horizontal als auch vertikal). Obwohl ich bei der -90 ° Rotation feststecke.

1. ROTATION (512x512)

Zur Zeit habe ich diesen Code (beide getPixel und setPixel sind meine eigenen Funktionen):

typedef struct _bitmap { 
    char file_path[PATH_MAX+1]; 
    char magic_number[3]; 
    unsigned int size; 
    unsigned char application[5]; 
    unsigned int start_offset; 
    unsigned int bitmapHeaderSize; 
    unsigned int width; 
    unsigned int height; 
    unsigned short int depth; 
    unsigned char* header; 
    PIXEL* raster; 
} BITMAP; 

void rotate(BITMAP* bmp) { 
    int i; 
    int j; 
    PIXEL* originalPixel; 
    BITMAP* originalBmp; 

    deepCopyBitmap(bmp, originalBmp); 

    for(j=1; j <= bmp->height; j++) { 
     for(i=1; i <= bmp->width; i++) { 
      originalPixel=getPixel(originalBmp->raster, bmp->width, bmp->height, j, i); 
      setPixel(bmp->raster, bmp->width, bmp->height, (bmp->width + 1 - i), j, originalPixel); 
     } 
    }     
} 

void deepCopyBitmap(BITMAP* bmp, BITMAP* copy) { 
    *copy = *bmp; 
    if (copy->raster) { 
     copy->raster = malloc(copy->height * sizeof(*copy->raster)); 
     for (int i = 0; i < copy->height; i++) { 
      copy->raster[i] = malloc(copy->width * sizeof(*copy->raster[i])); 
      memcpy(copy->raster[i], bmp->raster[i], copy->width * sizeof(*copy->raster[i])); 
     } 
    } 
} 

indirection requires pointer operand ('PIXEL' (aka 'struct _pixel') invalid) 
      copy->raster[i] = malloc(copy->width * sizeof(*copy->raster[i])); 
                  ^~~~~~~~~~~~~~~~ 
indirection requires pointer operand ('PIXEL' (aka 'struct _pixel') invalid) 
      memcpy(copy->raster[i], bmp->raster[i], copy->width * sizeof(*copy->raster[i])); 
                     ^~~~~~~~~~~~~~~~ 
expanded from macro 'memcpy' __builtin___memcpy_chk (dest, src, len, __darwin_obsz0 (dest)) 

Dies dreht richtig die erste Diagonale Teil des Bildes, aber der zweite Teil ist völlig falsch (zweimal ein Teil der ersten Diagonale).

Ich denke, das Problem ist, tauschen Pixel um und auf halbem Weg beginne ich bereits vertauschte Pixel zu tauschen. Also habe ich versucht, meine BMP zu einer Original-Bitmap (originalBmp) und einer gedrehten (gedrehtenBmp) zu duplizieren. Obwohl ich denke, es kopiert nur die Referenz. Jeder hat eine Idee, wie ich ein Duplikat bmp erstellen?

As example (sorry für den Rauch img): Ich möchte die vertikalen Linien (links), drehen -90deg, so wird es horizontale Linien (rechts). Obwohl der linke diagonale Teil korrekt ist. Aber der rechte Teil der Diagonale ist falsch, wenn ein Stück der linken Diagonale kopiert wird. Ich denke, weil es Pixel tauscht, die bereits in der BMP-Datei ausgetauscht werden.

2. ROTATION (512x1024)

Was passiert, wenn die Höhe oder Breite das Doppelte der anderen ist? Jeder weiß, wie man damit anfängt?

3. ZOOM (200%)

Wer weiß, wie dies zu tun? Holen Sie die mittleren Pixel der Bitmap, und machen Sie sie zweimal am Anfang des Bildes, oder gibt es eine bessere/sauberere Lösung?

1 2 3 4 5 6 7 8  3 3 4 4 5 5 6 6 
2 2 3 4 5 6 7 8  3 3 4 4 5 5 6 6 
3 3 3 4 5 6 7 8  4 4 4 4 5 5 6 6 
4 4 4 4 5 6 7 8  4 4 4 4 5 5 6 6 
5 5 5 5 5 6 7 8  5 5 5 5 5 5 6 6 
6 6 6 6 6 6 7 8  5 5 5 5 5 5 6 6 
7 7 7 7 7 7 7 8  6 6 6 6 6 6 6 6 
8 8 8 8 8 8 8 8  6 6 6 6 6 6 6 6 
+0

Zoom von 200 % == verdoppeln jedes Pixel in beide Richtungen, also wird jedes vier. Hängt von der Implementierung ab, wenn das Ergebnis größer oder nur ein beschnittenes Teil sein soll. Nicht Rechteck, hängt wieder von der Implementierung ab. –

+0

Ich kenne die 'setPixel'- und' getPixel'-Funktionen nicht, aber ich finde es merkwürdig, dass die Indizes ('i' und' j') bei 1 beginnen. Ist das absichtlich? In C würden Sie normalerweise von 0 ausgehen. – 4386427

+0

Haben Sie den Code mit einem Debugger ausgeführt, indem Sie alle relevanten Variablen überprüft haben? – alk

Antwort

0

Von Ihrem Code scheint es klar, dass beide originalBmp und bmp sind Zeiger auf einige BMP-Typ. Wenn Sie also originalBmp=bmp; tun, erhalten Sie nur zwei Zeiger, die auf denselben BMP zeigen, d. H. Sie arbeiten mit den gleichen Daten.

Ich nehme an, Sie haben so etwas wie

struct BMP 
{ 
    // .... 
}; 

Wenn das der Fall ist, dass Sie eine Kopie wie diese machen können:

struct BMP originalBmp = *bmp; 

Wenn originalBmp verwenden müssen Sie die . Schreibweise verwenden, z.B. originalBmp.raster

EDIT Ein alternativer Ansatz

Anstatt eine Kopie des Original bmp machen Sie die Drehung direkt auf dem Original tun könnte. Jede Rotation umfasst 4 Standorte.Sie können die vier Speicherorte zuerst in temporäre Variablen kopieren und dann an ihren endgültigen Speicherort schreiben.

Für eine einfache Matrix es so etwas wie dies sein könnte:

#include <stdio.h> 

#define WIDTH 4 

// display function 
void d(int t[WIDTH][WIDTH]) 
{ 
    int i, j; 
    for (i=0; i<WIDTH;i++) 
    { 
     for (j=0; j<WIDTH; j++) 
     { 
      printf("%d ", t[i][j]); 
     } 
     printf("\n"); 
    } 
} 

int main(void) { 
    int org[WIDTH][WIDTH]; 
    int i, j; 

    // Just initialize the matrix 
    for (i=0; i<WIDTH;i++) 
    { 
     for (j=0; j<WIDTH; j++) 
     { 
      org[i][j] = 10 + i*5 + j; 
     } 
    } 

    printf("Original\n"); 
    d(org); 

    // Rotate the matrix 
    for (j=0; j < (WIDTH/2); j++) 
    { 
     for (i=0; i < ((WIDTH+1)/2); i++) 
     { 
      int t1 = org[j][i]; 
      int t2 = org[i][WIDTH-1-j]; 
      int t3 = org[WIDTH-1-j][WIDTH-1-i]; 
      int t4 = org[WIDTH-1-i][j]; 

      org[j][i] = t2; 
      org[i][WIDTH-1-j] = t3; 
      org[WIDTH-1-j][WIDTH-1-i] = t4; 
      org[WIDTH-1-i][j] = t1; 
     } 
    } 
    printf("Rotated\n"); 
    d(org); 
    return 0; 
} 

erhalten Sie folgende Ausgabe:

Original 
10 11 12 13 
15 16 17 18 
20 21 22 23 
25 26 27 28 
Rotated 
13 18 23 28 
12 17 22 27 
11 16 21 26 
10 15 20 25 

Wechsel zu #define WIDTH 5 und es folgende Ausgabe:

Original 
10 11 12 13 14 
15 16 17 18 19 
20 21 22 23 24 
25 26 27 28 29 
30 31 32 33 34 
Rotated 
14 19 24 29 34 
13 18 23 28 33 
12 17 22 27 32 
11 16 21 26 31 
10 15 20 25 30 
+0

Ich habe mein Codebeispiel aktualisiert. Versuchte Ihre Lösung und geben Sie auch einige weitere Details bezüglich der Funktion. Obwohl das Ergebnis immer noch das gleiche ist, glaube ich nicht, dass es die Daten in originalBmp/rotierteBmp "dupliziert". –

+0

@PeterVanGorp - Sie sollten wahrscheinlich zeigen, wie die 'BITMAP' aussieht. Wenn die dynamische Zuordnung verwendet wird, müssen Sie eine Deep-Kopie erstellen. – 4386427

+0

Ich habe die BITMAP hinzugefügt –