c语言给bmp图片加水印
时间: 2023-08-04 22:08:32 浏览: 46
可以使用C语言的图像处理库来给bmp图片添加水印,比如OpenCV库。下面是一个简单的示例代码:
```c
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
// 读取原始图片
Mat img = imread("input.bmp", IMREAD_COLOR);
// 创建水印
Mat watermark = Mat::zeros(img.size(), img.type());
putText(watermark, "Watermark Text", Point(50, 50), FONT_HERSHEY_SIMPLEX, 1, Scalar(255, 255, 255), 2, LINE_AA);
// 在原始图片上添加水印
addWeighted(img, 0.7, watermark, 0.3, 0, img);
// 保存添加水印后的图片
imwrite("output.bmp", img);
return 0;
}
```
这个示例代码使用了OpenCV库来读取原始图片,创建水印,将水印添加到原始图片上,并保存添加水印后的图片。其中,addWeighted函数用于将原始图片和水印图像进行加权融合,从而实现添加水印的效果。具体的实现细节可以根据需求进行调整。
相关问题
c语言给bmp图片加水印,外部函数实现,传入参数为加需要水印的图片文件名
在 C 语言中,可以使用外部函数来实现给 BMP 图片加水印。
首先,需要打开需要加水印的图片文件,并将其作为二进制数据读取到内存中。然后,可以使用 BMP 文件的格式信息来找到图像数据的位置。接下来,就可以在图像数据的上方加上文本水印或者图像水印。最后,将修改后的图像数据写回文件中,就可以得到加了水印的 BMP 图片。
以下是一个示例函数的实现:
```
void add_watermark(const char* filename)
{
// 打开文件
FILE* file = fopen(filename, "rb+");
if (file == NULL) {
// 文件打开失败
return;
}
// 读取文件头
BMP_FILE_HEADER file_header;
fread(&file_header, sizeof(BMP_FILE_HEADER), 1, file);
// 读取信息头
BMP_INFO_HEADER info_header;
fread(&info_header, sizeof(BMP_INFO_HEADER), 1, file);
// 计算图像数据的位置
int data_offset = file_header.offset;
// 读取图像数据
char* data = malloc(info_header.image_size);
fseek(file, data_offset, SEEK_SET);
fread(data, info_header.image_size, 1, file);
// 在图像数据上方加上水印
// ...
// 将修改后的图像数据写回文件
fseek(file, data_offset, SEEK_SET);
fwrite(data, info_header.image_size, 1, file);
// 关闭文件并释放内存
fclose(file);
free(data);
}
```
在上面的代码中
帮我使用C语言设计一个包含LSB算法、DFT算法、DCT算法的基于图像的数字水印算法
好的,以下是一个基于图像的数字水印算法的C语言实现,其中包含LSB算法、DFT算法和DCT算法。
LSB算法:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 1024
// 将字符转换成二进制字符串
void charToBinary(char c, char *binary)
{
for (int i = 7; i >= 0; i--)
{
binary[7 - i] = ((c >> i) & 1) + '0';
}
binary[8] = '\0';
}
// 将二进制字符串转换成字符
char binaryToChar(char *binary)
{
char c = 0;
for (int i = 0; i < 8; i++)
{
c |= (binary[i] - '0') << (7 - i);
}
return c;
}
// LSB算法加密
void lsbEncrypt(FILE *inputImage, FILE *outputImage, char *text)
{
unsigned char byte;
char binary[9];
while ((byte = fgetc(inputImage)) != EOF)
{
// 如果还有待加密的字符
if (*text != '\0')
{
// 将待加密的字符转换成二进制字符串
charToBinary(*text++, binary);
// 修改最低位
binary[7] = (byte & 1) ^ (binary[7] - '0') + '0';
byte = strtol(binary, NULL, 2);
}
fputc(byte, outputImage);
}
}
// LSB算法解密
void lsbDecrypt(FILE *inputImage, char *text)
{
unsigned char byte;
char binary[9] = {0};
int i = 0;
while ((byte = fgetc(inputImage)) != EOF)
{
// 获取最低位
binary[i++] = byte & 1;
// 如果已经获取了8个二进制位,转换成字符,并且重新开始获取
if (i == 8)
{
*text++ = binaryToChar(binary);
memset(binary, 0, sizeof(binary));
i = 0;
}
}
}
// DFT变换
void dft(int *data, int size, int inverse)
{
double pi2 = 8 * atan(1.0);
double angle, real, imag;
int *result = malloc(sizeof(int) * size);
for (int i = 0; i < size; i++)
{
real = 0;
imag = 0;
for (int j = 0; j < size; j++)
{
angle = pi2 * i * j / size;
if (inverse)
{
angle = -angle;
}
real += data[j] * cos(angle);
imag += data[j] * sin(angle);
}
if (inverse)
{
real /= size;
imag /= size;
}
result[i] = (int)(sqrt(real * real + imag * imag) + 0.5);
}
memcpy(data, result, sizeof(int) * size);
free(result);
}
// DCT变换
void dct(int *data, int size, int inverse)
{
double pi = 4 * atan(1.0);
double angle, real, imag;
int *result = malloc(sizeof(int) * size);
for (int i = 0; i < size; i++)
{
real = 0;
imag = 0;
for (int j = 0; j < size; j++)
{
angle = pi * (j + 0.5) * i / size;
if (inverse)
{
angle = -angle;
}
real += data[j] * cos(angle);
imag += data[j] * sin(angle);
}
if (inverse)
{
real /= size;
imag /= size;
}
result[i] = (int)(sqrt(real * real + imag * imag) + 0.5);
}
memcpy(data, result, sizeof(int) * size);
free(result);
}
// 数字水印加密
void watermarkEncrypt(FILE *inputImage, FILE *outputImage, char *text)
{
unsigned char byte;
int data[MAX_SIZE];
int size = 0;
// 读取图像数据
while ((byte = fgetc(inputImage)) != EOF)
{
data[size++] = byte;
}
// 对图像数据进行DCT变换和DFT变换
dct(data, size, 0);
dft(data, size, 0);
// 对待加密文本进行LSB算法加密
lsbEncrypt(inputImage, outputImage, text);
// 对图像数据进行DFT变换和DCT变换
dft(data, size, 1);
dct(data, size, 1);
// 将加密后的图像数据写入输出文件
for (int i = 0; i < size; i++)
{
fputc(data[i], outputImage);
}
}
// 数字水印解密
void watermarkDecrypt(FILE *inputImage, char *text)
{
unsigned char byte;
int data[MAX_SIZE];
int size = 0;
// 读取图像数据
while ((byte = fgetc(inputImage)) != EOF)
{
data[size++] = byte;
}
// 对图像数据进行DCT变换和DFT变换
dct(data, size, 0);
dft(data, size, 0);
// 对加密后的图像数据进行LSB算法解密
lsbDecrypt(inputImage, text);
// 对图像数据进行DFT变换和DCT变换
dft(data, size, 1);
dct(data, size, 1);
}
```
该代码中,`lsbEncrypt`和`lsbDecrypt`分别是LSB算法的加密和解密函数,`dft`和`dct`分别是DFT变换和DCT变换函数,`watermarkEncrypt`和`watermarkDecrypt`分别是数字水印加密和解密函数。
使用该代码实现数字水印加密和解密的步骤如下:
```c
int main()
{
char text[] = "Hello world!";
FILE *inputImage = fopen("input.bmp", "rb");
FILE *outputImage = fopen("output.bmp", "wb");
// 数字水印加密
watermarkEncrypt(inputImage, outputImage, text);
fclose(inputImage);
fclose(outputImage);
inputImage = fopen("output.bmp", "rb");
// 数字水印解密
watermarkDecrypt(inputImage, text);
printf("Decrypted text: %s\n", text);
fclose(inputImage);
return 0;
}
```