使用vs2019,不引用库函数生成三层影像金字塔且可以输出图片的c语言代码
时间: 2023-06-19 11:05:41 浏览: 55
以下是使用vs2019,不引用库函数生成三层影像金字塔且可以输出图片的c语言代码:
```c
#include <stdio.h>
#include <stdlib.h>
// 定义图像宽度和高度
#define WIDTH 512
#define HEIGHT 512
// 定义金字塔层数
#define LEVELS 3
// 定义内存分配函数
#define mymalloc(size) ({ \
void *ptr = malloc(size); \
if (!ptr) { \
fprintf(stderr, "Memory allocation failed.\n"); \
exit(1); \
} \
ptr; \
})
// 定义图像结构体
typedef struct Image {
unsigned char *data; // 图像数据
int width; // 图像宽度
int height; // 图像高度
} Image;
// 创建图像
Image *create_image(int width, int height) {
Image *img = mymalloc(sizeof(Image));
img->data = mymalloc(width * height);
img->width = width;
img->height = height;
return img;
}
// 释放图像
void free_image(Image *img) {
free(img->data);
free(img);
}
// 读取图像
Image *read_image(const char *filename) {
FILE *fp = fopen(filename, "rb");
if (!fp) {
fprintf(stderr, "Failed to open file %s.\n", filename);
exit(1);
}
char buf[54];
fread(buf, 1, 54, fp); // 跳过 BMP 文件头
Image *img = create_image(WIDTH, HEIGHT);
fread(img->data, 1, WIDTH * HEIGHT, fp);
fclose(fp);
return img;
}
// 写入图像
void write_image(const char *filename, Image *img) {
FILE *fp = fopen(filename, "wb");
if (!fp) {
fprintf(stderr, "Failed to write file %s.\n", filename);
exit(1);
}
char buf[54] = {
0x42, 0x4D, // BMP 文件头
0x36, 0x0C, 0x00, 0x00, // 文件大小(12 MB)
0x00, 0x00, 0x00, 0x00, // 保留字段
0x36, 0x00, 0x00, 0x00, // 数据偏移量(54 字节)
0x28, 0x00, 0x00, 0x00, // 信息头大小(40 字节)
0x00, 0x02, 0x00, 0x00, // 图像宽度(512 像素)
0x00, 0x02, 0x00, 0x00, // 图像高度(512 像素)
0x01, 0x00, // 颜色平面数
0x08, 0x00, // 每个像素的位数(8 位)
0x00, 0x00, 0x00, 0x00, // 压缩方式(不压缩)
0x00, 0x0C, 0x00, 0x00, // 图像数据大小(12 MB)
0x00, 0x00, 0x00, 0x00, // 水平分辨率
0x00, 0x00, 0x00, 0x00, // 垂直分辨率
0x00, 0x00, 0x00, 0x00, // 颜色索引数
0x00, 0x00, 0x00, 0x00 // 重要颜色索引数
};
fwrite(buf, 1, 54, fp); // 写入 BMP 文件头
fwrite(img->data, 1, WIDTH * HEIGHT, fp);
fclose(fp);
}
// 缩小图像
void shrink_image(Image *src, Image *dst) {
int dst_w = dst->width;
int dst_h = dst->height;
int src_w = src->width;
int src_h = src->height;
for (int y = 0; y < dst_h; y++) {
for (int x = 0; x < dst_w; x++) {
int sum = 0;
for (int j = 0; j < 2; j++) {
for (int i = 0; i < 2; i++) {
int px = x * 2 + i;
int py = y * 2 + j;
if (px < src_w && py < src_h) {
sum += src->data[py * src_w + px];
}
}
}
dst->data[y * dst_w + x] = sum / 4;
}
}
}
int main() {
// 读取原始图像
Image *src = read_image("lena.bmp");
// 创建金字塔
Image *pyramid[LEVELS];
pyramid[0] = src;
for (int i = 1; i < LEVELS; i++) {
int w = pyramid[i - 1]->width / 2;
int h = pyramid[i - 1]->height / 2;
pyramid[i] = create_image(w, h);
shrink_image(pyramid[i - 1], pyramid[i]);
}
// 输出金字塔
for (int i = 0; i < LEVELS; i++) {
char filename[32];
sprintf(filename, "pyramid%d.bmp", i);
write_image(filename, pyramid[i]);
}
// 释放内存
for (int i = 1; i < LEVELS; i++) {
free_image(pyramid[i]);
}
free_image(src);
return 0;
}
```
代码中使用了一个自定义的内存分配函数 `mymalloc`,可以自动判断内存分配是否成功。主函数中先读取原始图像 `lena.bmp`,然后创建一个三层的金字塔,最后输出每一层的结果到磁盘上。在生成金字塔的过程中,使用了一个 `shrink_image` 函数来缩小图像。最后需要记得释放分配的内存。