我最近在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
答案 0 :(得分:0)
从您的代码中可以看出,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