【发布时间】:2016-04-18 06:49:38
【问题描述】:
我最近正在为一个在学校遇到问题的朋友检查 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
【问题讨论】:
-
放大 200% == 在两个方向上每个像素加倍,所以每个像素都变成四个。如果您希望结果更大或只是裁剪部分,则取决于实施。不是矩形,又要看具体实现了。
-
我不知道
setPixel和getPixel函数,但我似乎很奇怪索引(i和j)从1 开始。这是故意的吗?在 C 语言中,您通常会从 0 开始。 -
您是否使用调试器运行代码,逐步检查所有相关变量?
-
"... 只学过 java 和 C#,虽然会很容易" 显然不是... ;-) C 那时更“低级” Java 或 C#。您想了解数组、指针及其关系,以及使用
malloc()/calloc()和free()进行动态内存管理。