C++ 怎么把24位图中不是纯黑的点去掉高效算法代码实现
时间: 2024-05-02 22:17:45 浏览: 10
以下是一种高效算法,实现将24位图中不是纯黑的点去除。
1.将图像转换为灰度图像。
2.创建一个二维数组,大小与图像相同,用于存储每个像素点的灰度值。
3.遍历每个像素点,将其灰度值存储到数组中。
4.遍历每个像素点,如果其灰度值不为0,则将其标记为需要保留的点。
5.将需要保留的点的坐标存储到一个列表中。
6.创建一个新的图像,大小与原图相同。
7.遍历需要保留的点的坐标列表,将这些点在新图像中设置为黑色。
以下是C语言代码实现:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <stdint.h>
typedef struct {
uint8_t r;
uint8_t g;
uint8_t b;
} pixel_t;
typedef struct {
pixel_t *pixels;
size_t width;
size_t height;
} bitmap_t;
void bitmap_set_pixel(bitmap_t *bitmap, size_t x, size_t y, pixel_t pixel) {
bitmap->pixels[y * bitmap->width + x] = pixel;
}
pixel_t bitmap_get_pixel(bitmap_t *bitmap, size_t x, size_t y) {
return bitmap->pixels[y * bitmap->width + x];
}
bitmap_t *bitmap_create(size_t width, size_t height) {
bitmap_t *bitmap = malloc(sizeof(bitmap_t));
bitmap->pixels = calloc(width * height, sizeof(pixel_t));
bitmap->width = width;
bitmap->height = height;
return bitmap;
}
void bitmap_destroy(bitmap_t *bitmap) {
free(bitmap->pixels);
free(bitmap);
}
bitmap_t *bitmap_load(const char *filename) {
FILE *file = fopen(filename, "rb");
if (!file) {
return NULL;
}
uint8_t header[54];
fread(header, sizeof(uint8_t), 54, file);
size_t width = *(uint32_t *)&header[18];
size_t height = *(uint32_t *)&header[22];
bitmap_t *bitmap = bitmap_create(width, height);
size_t row_size = width * sizeof(pixel_t);
size_t padding_size = (4 - (row_size % 4)) % 4;
uint8_t padding[3];
for (size_t y = 0; y < height; y++) {
fread(bitmap->pixels + (y * width), sizeof(pixel_t), width, file);
fread(padding, sizeof(uint8_t), padding_size, file);
}
fclose(file);
return bitmap;
}
bool bitmap_save(bitmap_t *bitmap, const char *filename) {
FILE *file = fopen(filename, "wb");
if (!file) {
return false;
}
uint8_t header[54] = {
0x42, 0x4D, 0x36, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
0x36, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00,
0x13, 0x0B, 0x00, 0x00, 0x13, 0x0B, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
size_t width = bitmap->width;
size_t height = bitmap->height;
*(uint32_t *)&header[18] = (uint32_t)width;
*(uint32_t *)&header[22] = (uint32_t)height;
size_t row_size = width * sizeof(pixel_t);
size_t padding_size = (4 - (row_size % 4)) % 4;
uint8_t padding[3] = {0, 0, 0};
fwrite(header, sizeof(uint8_t), 54, file);
for (size_t y = 0; y < height; y++) {
fwrite(bitmap->pixels + (y * width), sizeof(pixel_t), width, file);
fwrite(padding, sizeof(uint8_t), padding_size, file);
}
fclose(file);
return true;
}
void bitmap_grayscale(bitmap_t *bitmap) {
for (size_t y = 0; y < bitmap->height; y++) {
for (size_t x = 0; x < bitmap->width; x++) {
pixel_t pixel = bitmap_get_pixel(bitmap, x, y);
uint8_t gray = (uint8_t)(0.299 * pixel.r + 0.587 * pixel.g + 0.114 * pixel.b);
pixel.r = gray;
pixel.g = gray;
pixel.b = gray;
bitmap_set_pixel(bitmap, x, y, pixel);
}
}
}
void bitmap_remove_nonblack(bitmap_t *bitmap) {
bool *keep = calloc(bitmap->width * bitmap->height, sizeof(bool));
size_t count = 0;
for (size_t y = 0; y < bitmap->height; y++) {
for (size_t x = 0; x < bitmap->width; x++) {
pixel_t pixel = bitmap_get_pixel(bitmap, x, y);
if (pixel.r != 0 || pixel.g != 0 || pixel.b != 0) {
keep[y * bitmap->width + x] = true;
count++;
}
}
}
bitmap_t *new_bitmap = bitmap_create(bitmap->width, bitmap->height);
for (size_t y = 0; y < bitmap->height; y++) {
for (size_t x = 0; x < bitmap->width; x++) {
if (keep[y * bitmap->width + x]) {
bitmap_set_pixel(new_bitmap, x, y, (pixel_t){0, 0, 0});
}
}
}
memcpy(bitmap->pixels, new_bitmap->pixels, bitmap->width * bitmap->height * sizeof(pixel_t));
bitmap->width = new_bitmap->width;
bitmap->height = new_bitmap->height;
free(keep);
bitmap_destroy(new_bitmap);
}
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "Usage: %s <input_file> <output_file>\n", argv[0]);
return 1;
}
const char *input_file = argv[1];
const char *output_file = argv[2];
bitmap_t *bitmap = bitmap_load(input_file);
if (!bitmap) {
fprintf(stderr, "Error: Failed to load input file '%s'\n", input_file);
return 1;
}
bitmap_grayscale(bitmap);
bitmap_remove_nonblack(bitmap);
if (!bitmap_save(bitmap, output_file)) {
fprintf(stderr, "Error: Failed to save output file '%s'\n", output_file);
return 1;
}
bitmap_destroy(bitmap);
return 0;
}
```