C 位图 : rotation and zoom

标签 c bitmap rotation zooming

我最近正在为一位在学校遇到问题的 friend 检查 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) 和一个旋转位图 (rotatedBmp)。虽然我认为它只是复制引用文献。 有人知道如何创建重复的 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

最佳答案

从您的代码中可以清楚地看出,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 

关于C 位图 : rotation and zoom,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36687160/

相关文章:

c - getchar 是否定义为宏?

c - 当程序终止时,使用未释放的 malloc 分配的内存会发生什么情况?

css - 变换 :rotate not just rotates but also translates

objective-c - CGAffineTransform 使旋转效果不佳

c - libwebsockets libwebsocket_client_connect 函数参数

连接所有参数(可执行文件名称除外)

java - Android Java,在缩放的 Canvas 上绘制

java - 低质量图像android开发

android - bitmap.getWidth() 或 bitmap.getHeight() 的单位是什么

ios - View 通过平移手势在旋转时奇怪地移动