RGB源数据操作: 在图片上添加中文水印

简介: RGB源数据操作: 在图片上添加中文水印

一、运行环境介绍

Linux系统: Redhat6.3 (32位)


gcc 版本 4.4.6 20120305 (Red Hat 4.4.6-4) (GCC)


二、功能介绍

创建一张BMP图片,将图片当做画板,在在图片的指定位置绘制中文。


三、核心代码

可以传入任意尺寸的图片进行生成绘制。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#pragma pack(1) //强制1个字节对齐
//BMP的文件头
struct _BMP_HEAD
{
    char type[2]; //图片的类型 "BM"
    unsigned int size; //文件大小
    unsigned short  r1; //保留1
    unsigned short  r2; //保留2
    unsigned int seek; //数据偏移字节(真实像素点数据)
};
//BMP的参数信息
struct _BMP_INFO
{
    unsigned int size; //当前结构体大小
    unsigned int w; //宽度
    unsigned int h; //高度
    unsigned short flag; //固定为1
    unsigned short bit; //像素点的位数
    unsigned int r1; //压缩方式  0
    unsigned int r2; //水平分辨率
    unsigned int r3; //垂直分辨率
    unsigned int r4; //垂直分辨率
    unsigned int r5; //引用色彩
    unsigned int r6; //关键色彩
};
/*
函数功能: 显示像素点
*/
void Display_Point(char *head,int w,int x,int y,int c)
{
    unsigned char *p=(unsigned char *)(head+w*3*y+x*3);
    *(p+0)=(c>>0)&0xFF;
    *(p+1)=(c>>8)&0xFF;
    *(p+2)=(c>>16)&0xFF;
}
/*
函数功能: 显示一个数据
函数参数:
char *font 取模数据的首地址  (横向取模--高位在前)
int w  取模字体的宽度
int h  取模字体的高度
*/
void Display_Data(char *font,int w,int h,char *image_head,int image_w,int x,int y)
{
    int i,j;
    int x0=x;
    unsigned char data;
    for(i=0;i<w/8*h;i++)
    {
        data=font[i];
        for(j=0;j<8;j++)
        {
            if(data&0x80)  //画前景色
            {
                Display_Point(image_head,image_w,x0,y,0xFF0033);
            }
            else //画背景色
            {
                //Display_Point(image_head,image_w,x0,y,0x0066FF);
            }
            x0++;
            data<<=1;
        }
        if(x0-x==w) //换行
        {
            x0=x;
            y++;
        }
    }
}
unsigned char font[]=
{
    /*--  文字:  钱  --*/
/*--  宋体36;  此字体下对应的点阵为:宽x高=48x48   --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x3C,
0x00,0x00,0x00,0x78,0x00,0x3F,0x00,0x00,0x00,0x7E,0x00,0x3E,0x78,0x00,0x00,0xFC,
0x00,0x3C,0x3E,0x00,0x00,0xF8,0x00,0x3C,0x1F,0x80,0x00,0xF0,0x00,0x3C,0x0F,0x80,
0x00,0xF0,0x00,0x3C,0x07,0xC0,0x01,0xF0,0x70,0x3E,0x03,0x80,0x01,0xFF,0xF8,0x1E,
0x01,0x80,0x01,0xFF,0xFC,0x1E,0x03,0x00,0x03,0xC0,0x00,0x1E,0x07,0x80,0x03,0xC0,
0x00,0x1F,0xFF,0xC0,0x07,0x80,0x03,0xFF,0xFF,0x80,0x07,0x80,0x1F,0xFE,0x00,0x00,
0x07,0x01,0xCE,0x1E,0x00,0x00,0x0F,0xFF,0xE0,0x1E,0x00,0x00,0x0F,0xFF,0xF0,0x1E,
0x00,0x00,0x1C,0x3C,0x00,0x1F,0x00,0x70,0x38,0x3C,0x00,0x0F,0x00,0xF8,0x38,0x3C,
0x00,0x0F,0x3F,0xFC,0x70,0x3C,0x00,0x1F,0xFF,0xE0,0x20,0x3C,0x1F,0xFF,0xC0,0x00,
0x00,0x3C,0x1F,0xEF,0x01,0x80,0x00,0x3C,0x6C,0x0F,0x81,0xC0,0x1F,0xFF,0xF0,0x07,
0x83,0xE0,0x3F,0xFF,0xF8,0x07,0x87,0xF0,0x1E,0x3C,0x00,0x07,0x87,0xE0,0x00,0x3C,
0x00,0x07,0xCF,0x80,0x00,0x3C,0x00,0x03,0xDF,0x00,0x00,0x3C,0x00,0x03,0xFE,0x00,
0x00,0x3C,0x00,0x03,0xFC,0x00,0x00,0x3C,0x00,0x01,0xF8,0x0C,0x00,0x3C,0x18,0x01,
0xF0,0x0C,0x00,0x3C,0x78,0x03,0xF0,0x1C,0x00,0x3D,0xF0,0x0F,0xF8,0x1C,0x00,0x3F,
0xC0,0x1F,0x7C,0x1C,0x00,0x3F,0x80,0x3E,0x3E,0x3C,0x00,0x7F,0x00,0xFC,0x1F,0x3C,
0x00,0x7E,0x01,0xF0,0x0F,0xBC,0x00,0x7C,0x07,0xC0,0x07,0xFC,0x00,0x38,0x1F,0x00,
0x03,0xFC,0x00,0x10,0x7C,0x00,0x01,0xFC,0x00,0x00,0xE0,0x00,0x00,0xFC,0x00,0x00,
0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
int main(int argc,char **argv)
{
    if(argc!=4)
    {
        printf("传入的参数格式: ./a.out <新图片宽度> <新图片高度> <新图片的名称>\n");
        printf("例如: ./a.out 80 80 test.bmp");
        printf("传入的宽度和高度需要>=48\n");
        return 0;
    }
    /*1. 创建一张BMP图片*/
    FILE *fp=fopen(argv[3],"wb");
    if(fp==NULL)
    {
        printf("%s 文件创建失败.\n",argv[1]);
        return 0;
    }
    /*2. 创建BMP的文件头*/
    int cnt;
    struct _BMP_HEAD bmp_head;
    memset(&bmp_head,0,sizeof(struct _BMP_HEAD));
    //图片的类型
    bmp_head.type[0]='B';
    bmp_head.type[1]='M';
    //文件大小
    bmp_head.size=54+800*480*3;
    //数据偏移量
    bmp_head.seek=54;
    //写文件头
    cnt=fwrite(&bmp_head,1,sizeof(struct _BMP_HEAD),fp);
    printf("成功写入:%d 字节.\n",cnt);
    /*3. 写文件参数信息*/
    struct _BMP_INFO bmp_info;
    memset(&bmp_info,0,sizeof(struct _BMP_INFO));
    //当前结构体大小
    bmp_info.size=sizeof(struct _BMP_INFO);
    //图片的宽度和高度
    bmp_info.w=atoi(argv[1]);
    bmp_info.h=atoi(argv[2]);
    //图片的颜色位数
    bmp_info.bit=24;
    //标志位
    bmp_info.flag=1;
    //写入文件参数信息
    cnt=fwrite(&bmp_info,1,sizeof(struct _BMP_INFO),fp);
    printf("成功写入:%d 字节.\n",cnt);
    /*4.添加水印: 制作图片的数据*/
    int one_line_byte=bmp_info.w*3; //BMP图片一行的字节数
    while(one_line_byte%4!=0) //补齐4的倍数
    {
        one_line_byte++;
    }
    one_line_byte=one_line_byte-bmp_info.w*3; //得到需要补齐的字节数量
    //申请一个存放图片颜色数据的缓冲区
    char *head_p=malloc(bmp_info.w*3*bmp_info.h);
    //将缓冲区初始化
    memset(head_p,0xFF,bmp_info.w*3*bmp_info.h);
    //绘制水印
    Display_Data(font,48,48,head_p,bmp_info.w,10,10);
    /*5. 写入位图数据*/
    int w,h;
    char *tmp_p;
    for(h=bmp_info.h-1;h>=0;h--)
    {
        tmp_p=head_p+h*bmp_info.w*3;     //从缓冲区的最后一行开始读取
        fwrite(tmp_p,1,bmp_info.w*3,fp); //写一行数据
        if(one_line_byte) //判断是否需要补齐
        fwrite(tmp_p,1,one_line_byte,fp); //写补齐的数据(占位而已--没有显示作用)
    }
    /*6. 关闭文件*/
    fclose(fp);
    free(head_p);
    return 0;
}

四、运行效果

[wbyq@wbyq linux_c]$ gcc app.c 
[wbyq@wbyq linux_c]$ ./a.out 81 81 1.bmp 
成功写入:14 字节.
成功写入:40 字节.
[wbyq@wbyq linux_c]$ eog 1.bmp

image.png

目录
相关文章
|
5月前
|
人工智能 自然语言处理 API
图片转音乐模型来了!Image to Music V2 :只需上传一张照片,自动转换成与图片内容匹配的音频!
图片转音乐模型来了!Image to Music V2 :只需上传一张照片,自动转换成与图片内容匹配的音频!
254 1
|
存储 传感器 自动驾驶
几种常见的点云格式数据解析与在线预览
3D模型在线转换网站支持pcd、pts、xyz、las、laz、asc、ply等点云格式文件在线预览,同时支持将点云格式在线转换为ply、xyz等模型格式。
2603 1
|
11天前
|
计算机视觉 Python
Python实用记录(一):如何将不同类型视频按关键帧提取并保存图片,实现图片裁剪功能
这篇文章介绍了如何使用Python和OpenCV库从不同格式的视频文件中按关键帧提取图片,并展示了图片裁剪的方法。
38 0
|
3月前
|
PHP 数据安全/隐私保护 计算机视觉
ThinkPHP图片处理之压缩图片大小,图片处理之图片水印(添加平铺文字水印,并设置文字之间的间距和文字的角度)
ThinkPHP图片处理之压缩图片大小,图片处理之图片水印(添加平铺文字水印,并设置文字之间的间距和文字的角度)
57 1
|
4月前
|
存储 编解码 API
如何通过编程获取桌面分辨率、操作像素点颜色、保存位图和JPG格式图片,以及图片数据的处理和存储方式
如何通过编程获取桌面分辨率、操作像素点颜色、保存位图和JPG格式图片,以及图片数据的处理和存储方式
74 0
|
5月前
|
数据安全/隐私保护 Python
python 图片打水印 透明图片合并
python 图片打水印 透明图片合并
47 1
|
5月前
|
文字识别 数据挖掘 网络安全
Python实现avif图片转jpg格式并识别图片中的文字
在做数据分析的时候有些数据是从图片上去获取的,这就需要去识别图片上的文字。Python有很多库可以很方便的实现OCR识别图片中的文字。这里介绍用EasyOCR库进行图片文字识别。easyocr是一个比较流行的库,支持超过80种语言,识别率高,速度也比较快。
111 2
|
5月前
|
存储 传感器 编解码
图像格式:常见图像格式RAW, RGB, YUV&&图像格式的解析、格式转换和看图软件
图像格式:常见图像格式RAW, RGB, YUV&&图像格式的解析、格式转换和看图软件
1154 1
|
5月前
|
存储 传感器 监控
工业相机如何实现实时和本地Raw格式图像和Bitmap格式图像的保存和相互转换(C#代码,UI界面版)
工业相机如何实现实时和本地Raw格式图像和Bitmap格式图像的保存和相互转换(C#代码,UI界面版)
184 0
|
10月前
|
存储 数据安全/隐私保护 计算机视觉
PIL如何批量给图片添加文字水印?
PIL如何批量给图片添加文字水印?
58 1