C位图:旋转和缩放

时间:2016-04-18 06:49:38

标签: c bitmap rotation zoom

我最近在C上找到了一个在学校遇到问题的朋友。因为我只学习了java和C#,虽然这很容易。但目前仍坚持这一点。

我有一个项目读取一个小bmp(512x512)图像。我已经设法改变它上面的一些颜色并让它旋转(水平垂直)。虽然我坚持-90°旋转。

1。旋转(512x512)

目前我有这个代码(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))

这正确旋转了图像的第一个对角线部分,但第二个部分完全错误(第一个对角线的两倍)。

我认为问题是,在周围交换像素,我开始交换已交换的像素。所以我试图将我的bmp复制到原始位图(originalBmp)和一个旋转(rotateBmp)。虽然我认为它只是复制参考。 任何人都知道如何创建重复的bmp?

As example(对不起烟道img):我希望垂直线(左)转-90度,所以它变成水平线(右)。虽然左对角线部分是正确的。但是对角线的右边部分是不正确地复制左对角线的一部分。我认为因为它交换了已经在bmp文件中交换过的像素。

2。旋转(512x1024)

如果高度或宽度是另一个的两倍,会发生什么?任何人都知道如何开始这个?

第3。缩放(200%)

任何人都知道如何做到这一点?获取位图的中心像素,并在图像的开头两次,或者是否有更好/更清洁的解决方案?

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

1 个答案:

答案 0 :(得分:0)

从您的代码中可以看出,originalBmpbmp都是指向某些BMP类型的指针。因此,当你执行originalBmp=bmp;时,你只需要指向同一个BMP的两个指针,即它们对相同的数据进行操作。

我假设你有像

这样的东西
struct BMP
{
   // ....
};

如果是这种情况,你可以制作这样的副本:

struct BMP originalBmp = *bmp;

使用originalBmp时,您必须使用.表示法,例如originalBmp.raster

编辑另一种方法

您可以直接在原稿上进行旋转,而不是制作原始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;
}

这将输出:

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 

更改为#define WIDTH 5,它将输出:

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 
相关问题