我最近正在为一位在学校遇到问题的 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
最佳答案
从您的代码中可以清楚地看出,originalBmp
和bmp
都是指向某种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/