使用vs2019,不引用库函数生成三层影像金字塔且可以输出图片的c语言代码
时间: 2023-08-31 08:31:18 浏览: 144
### 回答1:
以下是一个简单的C语言代码,它可以生成三层影像金字塔并输出图片。该代码不依赖任何库函数。
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 定义图像结构体
typedef struct {
int width;
int height;
unsigned char* data;
} Image;
// 读取PGM格式图像
Image* readPGM(const char* filename) {
FILE* fp = fopen(filename, "rb");
if (fp == NULL) {
printf("Failed to open file: %s\n", filename);
return NULL;
}
char magic[3];
fscanf(fp, "%s", magic);
if (strcmp(magic, "P5") != 0) {
printf("Invalid PGM file format: %s\n", filename);
fclose(fp);
return NULL;
}
int width, height, maxval;
fscanf(fp, "%d %d %d", &width, &height, &maxval);
if (maxval != 255) {
printf("Unsupported PGM file format: %s\n", filename);
fclose(fp);
return NULL;
}
Image* img = (Image*)malloc(sizeof(Image));
img->width = width;
img->height = height;
img->data = (unsigned char*)malloc(width * height);
fread(img->data, 1, width * height, fp);
fclose(fp);
return img;
}
// 写入PGM格式图像
int writePGM(const char* filename, const Image* img) {
FILE* fp = fopen(filename, "wb");
if (fp == NULL) {
printf("Failed to open file: %s\n", filename);
return -1;
}
fprintf(fp, "P5\n%d %d\n255\n", img->width, img->height);
fwrite(img->data, 1, img->width * img->height, fp);
fclose(fp);
return 0;
}
// 生成金字塔
Image** generatePyramid(const Image* src, int levels) {
Image** pyramid = (Image**)malloc(sizeof(Image*) * levels);
pyramid[0] = src;
for (int i = 1; i < levels; i++) {
Image* prev = pyramid[i - 1];
int w = prev->width / 2;
int h = prev->height / 2;
Image* curr = (Image*)malloc(sizeof(Image));
curr->width = w;
curr->height = h;
curr->data = (unsigned char*)malloc(w * h);
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
int sum = prev->data[(y * 2) * prev->width + (x * 2)];
sum += prev->data[(y * 2) * prev->width + (x * 2 + 1)];
sum += prev->data[(y * 2 + 1) * prev->width + (x * 2)];
sum += prev->data[(y * 2 + 1) * prev->width + (x * 2 + 1)];
curr->data[y * w + x] = (unsigned char)(sum / 4);
}
}
pyramid[i] = curr;
}
return pyramid;
}
// 释放图像内存
void freeImage(Image* img) {
if (img != NULL) {
free(img->data);
free(img);
}
}
// 释放金字塔内存
void freePyramid(Image** pyramid, int levels) {
for (int i = 0; i < levels; i++) {
freeImage(pyramid[i]);
}
free(pyramid);
}
int main(int argc, char* argv[]) {
if (argc != 2) {
printf("Usage: %s <input_file.pgm>\n", argv[0]);
return -1;
}
// 读取输入图像
Image* src = readPGM(argv[1]);
if (src == NULL) {
return -1;
}
// 生成金字塔
Image** pyramid = generatePyramid(src, 3);
// 输出金字塔
for (int i = 0; i < 3; i++) {
char filename[256];
sprintf(filename, "level%d.pgm", i);
writePGM(filename, pyramid[i]);
}
// 释放内存
freeImage(src);
freePyramid(pyramid, 3);
return 0;
}
```
以上代码中,`Image` 结构体表示一个图像,包括图像的宽度、高度和像素数据。`readPGM` 函数可以读取 PGM 格式的图像文件,`writePGM` 函数可以将图像数据写入 PGM 格式的文件。`generatePyramid` 函数可以生成金字塔,其中 `levels` 参数指定金字塔的层数。
你可以使用以下命令编译该代码:
```
gcc -o pyramid.exe main.c
```
该代码将生成一个可执行文件 `pyramid.exe`,使用以下命令运行该程序:
```
pyramid.exe input.pgm
```
其中 `input.pgm` 是输入图像文件名。程序将生成三层金字塔,并将每一层的图像保存为 `level0.pgm`、`level1.pgm` 和 `level2.pgm`。
### 回答2:
使用VS2019,不引用库函数生成三层影像金字塔并输出图片的C语言代码如下:
```c
#include <stdio.h>
#include <stdlib.h>
typedef struct {
unsigned char* data;
int width;
int height;
} Image;
Image createImage(int width, int height) {
Image img;
img.width = width;
img.height = height;
img.data = (unsigned char*)malloc(width * height * sizeof(unsigned char));
return img;
}
void destroyImage(Image img) {
free(img.data);
}
void generatePyramid(Image img, Image* pyramid) {
pyramid[0] = img;
for (int i = 1; i < 3; i++) {
int newWidth = pyramid[i - 1].width / 2;
int newHeight = pyramid[i - 1].height / 2;
pyramid[i] = createImage(newWidth, newHeight);
for (int row = 0; row < newHeight; row++) {
for (int col = 0; col < newWidth; col++) {
int srcRow = row * 2;
int srcCol = col * 2;
pyramid[i].data[row * newWidth + col] = pyramid[i - 1].data[srcRow * pyramid[i - 1].width + srcCol];
}
}
}
}
void saveImage(Image img, const char* filename) {
FILE* file = fopen(filename, "wb");
if (file == NULL) {
printf("Failed to open file: %s\n", filename);
return;
}
fprintf(file, "P5\n%d %d\n255\n", img.width, img.height);
fwrite(img.data, sizeof(unsigned char), img.width * img.height, file);
fclose(file);
}
int main() {
// 读取原始图片并创建金字塔
Image sourceImg;
// 模拟从文件中读取图片的数据
sourceImg.width = 800;
sourceImg.height = 600;
sourceImg.data = (unsigned char*)malloc(sourceImg.width * sourceImg.height * sizeof(unsigned char));
// 填充图片数据
// ...
Image pyramid[3];
for (int i = 0; i < 3; i++) {
pyramid[i] = createImage(sourceImg.width, sourceImg.height);
}
generatePyramid(sourceImg, pyramid);
// 保存金字塔中的每一层图片
for (int i = 0; i < 3; i++) {
char filename[20];
sprintf(filename, "pyramid_layer_%d.pgm", i);
saveImage(pyramid[i], filename);
}
// 释放内存
destroyImage(sourceImg);
for (int i = 0; i < 3; i++) {
destroyImage(pyramid[i]);
}
return 0;
}
```
以上代码使用C语言实现了生成三层影像金字塔的功能,并将每一层金字塔保存成图片文件。注意,代码中的图片数据是模拟的,如果要使用真实的图片数据,你需要根据实际情况进行读取和填充。另外,为了简化代码,使用了PGM格式保存图片,如果需要保存其他格式的图片,你需要进行相应的修改。
### 回答3:
下面是使用VS2019编写的可以生成三层影像金字塔并输出图片的C语言代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
unsigned char r, g, b;
} Pixel;
typedef struct {
int width, height;
Pixel *data;
} Image;
Image loadImage(const char *filename) {
FILE *file = fopen(filename, "rb");
if (!file) {
fprintf(stderr, "Error opening file: %s\n", filename);
exit(1);
}
char format[4];
int width, height, maxVal;
fscanf(file, "%s\n%d %d\n%d\n", format, &width, &height, &maxVal);
if (strcmp(format, "P6") != 0 || maxVal != 255) {
fprintf(stderr, "Invalid image format: %s\n", format);
exit(1);
}
Image image;
image.width = width;
image.height = height;
image.data = (Pixel*)malloc(width * height * sizeof(Pixel));
fread(image.data, sizeof(Pixel), width * height, file);
fclose(file);
return image;
}
void saveImage(const char *filename, Image image) {
FILE *file = fopen(filename, "wb");
if (!file) {
fprintf(stderr, "Error opening file: %s\n", filename);
exit(1);
}
fprintf(file, "P6\n%d %d\n%d\n", image.width, image.height, 255);
fwrite(image.data, sizeof(Pixel), image.width * image.height, file);
fclose(file);
}
Image downsample(const Image *input) {
Image output;
output.width = input->width / 2;
output.height = input->height / 2;
output.data = (Pixel*)malloc(output.width * output.height * sizeof(Pixel));
for (int y = 0; y < output.height; y++) {
for (int x = 0; x < output.width; x++) {
int inX = x * 2;
int inY = y * 2;
int outIndex = y * output.width + x;
int inIndex = inY * input->width + inX;
output.data[outIndex] = input->data[inIndex];
}
}
return output;
}
int main() {
const char *filename = "input.ppm";
Image original = loadImage(filename);
Image level1 = downsample(&original);
Image level2 = downsample(&level1);
saveImage("level1.ppm", level1);
saveImage("level2.ppm", level2);
free(original.data);
free(level1.data);
free(level2.data);
return 0;
}
```
上述代码中,定义了Pixel结构体表示图片中的像素点,Image结构体表示图片。loadImage函数用于从文件中加载图片,saveImage函数用于保存图片。downsample函数用于将输入图像缩小一半并返回。在主函数中,首先加载原始图片,然后调用downsample函数生成第一层和第二层金字塔图像,最后存储金字塔图像。最后释放内存。
阅读全文