#include "image_opration.h"
// 初始化图片编辑器
ImageEditor* create_image_editor(const char* baseImagePath) {
ImageEditor* editor = (ImageEditor*)malloc(sizeof(ImageEditor));
if (!editor) return NULL;
// 读取基础图片
FILE* file = fopen(baseImagePath, "rb");
if (!file) {
free(editor);
return NULL;
}
BMPHeader header;
BMPInfoHeader infoHeader;
fread(&header, sizeof(BMPHeader), 1, file);
fread(&infoHeader, sizeof(BMPInfoHeader), 1, file);
editor->basePixels = (Pixel*)malloc(BASE_WIDTH * BASE_HEIGHT * sizeof(Pixel));
fseek(file, header.offset, SEEK_SET);
fread(editor->basePixels, sizeof(Pixel), BASE_WIDTH * BASE_HEIGHT, file);
fclose(file);
editor->count = 0;
pthread_mutex_init(&editor->lock, NULL);
return editor;
}
// 释放资源
void destroy_image_editor(ImageEditor* editor) {
if (!editor) return;
for (int i = 0; i < editor->count; i++) {
free(editor->images[i].pixels);
}
free(editor->basePixels);
pthread_mutex_destroy(&editor->lock);
free(editor);
}
// 添加小图片到指定位置
int add_image(ImageEditor* editor, const char* smallImagePath, int x, int y, const char* outputPath) {
pthread_mutex_lock(&editor->lock);
if (editor->count >= MAX_IMAGES) {
pthread_mutex_unlock(&editor->lock);
return 0;
}
// 读取小图片
FILE* file = fopen(smallImagePath, "rb");
if (!file) {
pthread_mutex_unlock(&editor->lock);
return 0;
}
BMPHeader header;
BMPInfoHeader infoHeader;
fread(&header, sizeof(BMPHeader), 1, file);
fread(&infoHeader, sizeof(BMPInfoHeader), 1, file);
SmallImage* img = &editor->images[editor->count];
img->pixels = (Pixel*)malloc(SMALL_SIZE * SMALL_SIZE * sizeof(Pixel));
fseek(file, header.offset, SEEK_SET);
fread(img->pixels, sizeof(Pixel), SMALL_SIZE * SMALL_SIZE, file);
fclose(file);
strcpy(img->path, smallImagePath);
img->x = x;
img->y = y;
img->width = SMALL_SIZE;
img->height = SMALL_SIZE;
editor->count++;
// 合成图片
Pixel* result = (Pixel*)malloc(BASE_WIDTH * BASE_HEIGHT * sizeof(Pixel));
memcpy(result, editor->basePixels, BASE_WIDTH * BASE_HEIGHT * sizeof(Pixel));
for (int i = 0; i < editor->count; i++) {
SmallImage* current = &editor->images[i];
for (int py = 0; py < current->height; py++) {
for (int px = 0; px < current->width; px++) {
int baseX = current->x + px;
int baseY = current->y + py;
if (baseX >= 0 && baseX < BASE_WIDTH && baseY >= 0 && baseY < BASE_HEIGHT) {
Pixel* src = ¤t->pixels[py * current->width + px];
Pixel* dest = &result[baseY * BASE_WIDTH + baseX];
*dest = *src; // 直接覆盖像素
}
}
}
}
// 保存结果
file = fopen(outputPath, "wb");
if (!file) {
free(result);
pthread_mutex_unlock(&editor->lock);
return 0;
}
BMPHeader newHeader = {0x4D42, 54 + BASE_WIDTH * BASE_HEIGHT * 4, 0, 0, 54};
BMPInfoHeader newInfoHeader = {
sizeof(BMPInfoHeader), BASE_WIDTH, BASE_HEIGHT, 1, 32, 0,
BASE_WIDTH * BASE_HEIGHT * 4, 0, 0, 0, 0
};
fwrite(&newHeader, sizeof(BMPHeader), 1, file);
fwrite(&newInfoHeader, sizeof(BMPInfoHeader), 1, file);
fwrite(result, sizeof(Pixel), BASE_WIDTH * BASE_HEIGHT, file);
fclose(file);
free(result);
pthread_mutex_unlock(&editor->lock);
return 1;
}
// 查找点击位置的小图片
int find_image_at(ImageEditor* editor, int x, int y) {
// 从后向前查找(最后添加的在最上面)
for (int i = editor->count - 1; i >= 0; i--) {
SmallImage* img = &editor->images[i];
if (x >= img->x && x < img->x + img->width &&
y >= img->y && y < img->y + img->height) {
return i;
}
}
return -1;
}
// 删除或移动图片
void handle_image_interaction(ImageEditor* editor, int startX, int startY, int endX, int endY, const char* outputPath) {
pthread_mutex_lock(&editor->lock);
int index = find_image_at(editor, startX, startY);
if (index == -1) {
pthread_mutex_unlock(&editor->lock);
return;
}
// 删除操作:起点和终点相同
if (startX == endX && startY == endY) {
free(editor->images[index].pixels);
// 移动数组元素填补空缺
for (int i = index; i < editor->count - 1; i++) {
editor->images[i] = editor->images[i + 1];
}
editor->count--;
}
// 移动操作
else {
int targetIndex = find_image_at(editor, endX, endY);
SmallImage* moved = &editor->images[index];
// 与目标位置图片交换
if (targetIndex != -1 && targetIndex != index) {
SmallImage target = editor->images[targetIndex];
editor->images[targetIndex] = *moved;
*moved = target;
}
// 移动到空白位置
else {
moved->x = endX - moved->width / 2;
moved->y = endY - moved->height / 2;
}
}
// 重新合成并保存图片
Pixel* result = (Pixel*)malloc(BASE_WIDTH * BASE_HEIGHT * sizeof(Pixel));
memcpy(result, editor->basePixels, BASE_WIDTH * BASE_HEIGHT * sizeof(Pixel));
for (int i = 0; i < editor->count; i++) {
SmallImage* current = &editor->images[i];
for (int py = 0; py < current->height; py++) {
for (int px = 0; px < current->width; px++) {
int baseX = current->x + px;
int baseY = current->y + py;
if (baseX >= 0 && baseX < BASE_WIDTH && baseY >= 0 && baseY < BASE_HEIGHT) {
Pixel* src = ¤t->pixels[py * current->width + px];
Pixel* dest = &result[baseY * BASE_WIDTH + baseX];
*dest = *src;
}
}
}
}
FILE* file = fopen(outputPath, "wb");
if (file) {
BMPHeader header = {0x4D42, 54 + BASE_WIDTH * BASE_HEIGHT * 4, 0, 0, 54};
BMPInfoHeader infoHeader = {
sizeof(BMPInfoHeader), BASE_WIDTH, BASE_HEIGHT, 1, 32, 0,
BASE_WIDTH * BASE_HEIGHT * 4, 0, 0, 0, 0
};
fwrite(&header, sizeof(BMPHeader), 1, file);
fwrite(&infoHeader, sizeof(BMPInfoHeader), 1, file);
fwrite(result, sizeof(Pixel), BASE_WIDTH * BASE_HEIGHT, file);
fclose(file);
}
free(result);
pthread_mutex_unlock(&editor->lock);
}
//叠加图片操作
void overlay_image_any_position(const char* backgroundPath,const char* foregroundPath,const char* outputImagePath,int startX,int startY)
{
// 创建编辑器
ImageEditor* editor = create_image_editor(backgroundPath);
// 添加小图片
add_image(editor, foregroundPath,startX, startY, outputImagePath);
// 释放资源
destroy_image_editor(editor);
}
//长按删除操作
void overlay_image_del(const char* backgroundPath,const char* outputImagePath,int startX,int startY,int end_x,int end_y)
{
// 创建编辑器
ImageEditor* editor = create_image_editor(backgroundPath);
// 模拟长按删除 (相同位置)
handle_image_interaction(editor, startX,startY,end_x,end_y,outputImagePath);
// 释放资源
destroy_image_editor(editor);
}
//长按移动交换操作
void overlay_image_swap(const char* backgroundPath,const char* outputImagePath,int startX,int startY,int end_x,int end_y)
{
// 创建编辑器
ImageEditor* editor = create_image_editor(backgroundPath);
// 模拟移动交换 (拖动到另一个图片位置)
handle_image_interaction(editor, startX,startY,end_x,end_y,outputImagePath);
// 释放资源
destroy_image_editor(editor);
}修改上述bmp为24位