2016-04-18 13 views
0

私は最近、学校に問題がある友人のCをチェックアウトしています。私はJavaとC#を学んだだけですが、それは簡単でしょう。しかし、現在これに固執しています。Cビットマップ:回転とズーム

私は小さなbmp(512x512)イメージを読んでいるプロジェクトがあります。私はそれにいくつかの色を変更し、それを回転させることに成功しました。私は-90°の回転で立ち往生しています。

1. ROTATION(512×512)

現在、私は(getPixelメソッドととsetPixel両方が自分自身の関数です)、このコードを持っている:

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)) 

これは正しく画像の最初の対角の部分を回転させ、第2部分は完全に間違っている(第1対角線の2倍の部分を有する)。

私は問題は、周囲のピクセルを交換し、途中で既に交換されたピクセルを交換し始めていると思います。だから、オリジナルのビットマップ(originalBmp)と1つのrotate(rotateBmp)に、私​​のbmpを複製しようとしました。私はそれが単に参照をコピーすると思うが。 誰でも私はどのようにbmpを重複して作成する考えがありますか?

As example(腹筋のため申し訳ありません):私は垂直線(左)を-90度回転させたいので、水平線(右)になります。左斜めの部分は正しいですが。しかし、対角線の右部分は、左斜めの部分をコピーすることが間違っています。私はそれが既にbmpファイルでスワップされているピクセルを交換するためだと思います。

2. ROTATION高さや幅が他の倍である場合はどうなりますか(512x1024)

?誰もがこれを始める方法を知っていますか?

3. ZOOM(200%)

これを行う方法を誰もが知っていますか?ビットマップの中央のピクセルを取得し、イメージの開始時に2回作成するか、より良い/よりクリーンなソリューションがありますか?あなたのコードから

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

ズーム200によって、それはこのようなものになる可能性があり、単純マトリクスについては

%==両方向のピクセルごとに2倍になるので、それぞれが4になります。結果がより大きくなるように、または切り取った部分だけを望む場合は、実装に依存します。矩形ではなく、実装にも依存します。 –

+0

'setPixel'と' getPixel'関数は分かりませんが、インデックス( 'i'と' j')が1から始まるのは奇妙です。 Cでは、通常0から開始します。 – 4386427

+0

デバッガを使用してコードを実行し、関連するすべての変数を検査していますか? – alk

答えて

0

originalBmpbmp両方は、いくつかのBMP型へのポインタであることは明らかと思われます。したがって、originalBmp=bmp;を実行すると、同じBMPを指す2つのポインタが得られます。つまり、同じデータで動作します。

struct BMP originalBmp = *bmp; 

originalBmpを使用して、あなたが.表記を使用し、例えば必要があります。

は、私はそのような場合は、あなたがこのようなコピーを作成することができますが、

struct BMP 
{ 
    // .... 
}; 

のようなものを持っていると仮定しますoriginalBmp.raster

EDIT別のアプローチ

代わりに、元のbmpファイルのコピーを作成するのは、元に直接回転を行うことができます。各ローテーションには4つの場所が含まれます。4つの場所を一時変数にコピーしてから、最終的な場所に書き込むことができます。この意志出力

#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; 
} 

#define WIDTH 5

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 

の変更と、それは出力は以下となります。

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

私のコード例を更新しました。 あなたの解決策を試してみて、機能に関するいくつかの詳細を教えてください。 結果は同じですが、私はそれがoriginalBmp/rotatedBmpのデータを「複製」するとは思わないのです。 –

+0

@PeterVanGorp - おそらく 'BITMAP'がどのように見えるのでしょうか?動的割り当てを使用する場合は、ディープコピーを行う必要があります。 – 4386427

+0

私はBITMAPを追加しました –

関連する問題