给BMP图片加水印

群里的小学弟问怎么给bmp图片加水印, 我就看了一下资料, 试着弄一下

//
//  main.c
//  BMPtes
//
//  Created by 西博尔 on 2017/9/7.
//  Copyright © 2017年 西博尔. All rights reserved.
//
#include <string.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>

#pragma  pack(1) //作用:C编译器将按照1个字节对齐,很关键
#define   WIDTHBYTES(bits) (((bits)+31)/32*4)

typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef long LONG;


//位图文件头信息结构定义
//其中不包含文件类型信息(由于结构体的内存结构决定,要是加了的话将不能正确读取文件信息)

typedef struct tagBITMAPFILEHEADER {
    unsigned short bfType;      // 19778,必须是BM字符串,对应的十六进制为0x4d42,十进制为19778,否则不是bmp格式文件
    unsigned int bfSize;        // 文件大小
    unsigned short bfReserved1; // 保留,必须设置为0
    unsigned short bfReserved2; // 保留,必须设置为0
    unsigned int bfOffBits;     // 从文件头到像素数据的偏移
} BITMAPFILEHEADER;

typedef struct tagBITMAPINFOHEADER {
    unsigned int biSize;        // 此结构体的大小
    int biWidth;                // 图像的宽
    int biHeight;               // 图像的高
    unsigned short biPlanes;    // 表示bmp图片的平面属,显然显示器只有一个平面,所以恒等于1
    unsigned short biBitCount;  // 一像素所占的位数,一般为24
    unsigned int biCompression; // 说明图象数据压缩的类型,0为不压缩。
    unsigned int biSizeImage;   // 像素数据所占大小, 这个值应该等于上面文件头结构中bfSize-bfOffBits
    int biXPelsPerMeter;        // 说明水平分辨率,用象素/米表示。一般为0
    int biYPelsPerMeter;        // 说明垂直分辨率,用象素/米表示。一般为0
    unsigned int biClrUsed;     // 说明位图实际使用的彩色表中的颜色索引数(设为0的话,则说明使用所有调色板项)。
    unsigned int biClrImportant;// 说明对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要。
} BITMAPINFOHEADER;




typedef struct tagRGBQUAD {
    //public:
    BYTE     rgbBlue; //该颜色的蓝色分量
    BYTE     rgbGreen; //该颜色的绿色分量
    BYTE     rgbRed; //该颜色的红色分量
    BYTE     rgbReserved; //保留值
} RGBQUAD;


void showBmpHead(BITMAPFILEHEADER* pBmpHead)
{
    printf("位图文件头:\n");
    printf("文件大小:%u\n",pBmpHead->bfSize);
    printf("保留字:%d\n",pBmpHead->bfReserved1);
    printf("保留字:%d\n",pBmpHead->bfReserved2);
    printf("实际位图数据的偏移字节数:%u\n",pBmpHead->bfOffBits);
    
}


void showBmpInforHead(BITMAPINFOHEADER* pBmpInforHead)
{
    printf("位图信息头:\n");
    printf("结构体的长度:%u\n",pBmpInforHead->biSize);
    printf("位图宽:%d\n",pBmpInforHead->biWidth);
    printf("位图高:%d\n",pBmpInforHead->biHeight);
    printf("biPlanes平面数:%d\n",pBmpInforHead->biPlanes);
    printf("biBitCount采用颜色位数:%d\n",pBmpInforHead->biBitCount);
    printf("压缩方式:%u\n",pBmpInforHead->biCompression);
    printf("biSizeImage实际位图数据占用的字节数:%u\n",pBmpInforHead->biSizeImage);
    printf("X方向分辨率:%d\n",pBmpInforHead->biXPelsPerMeter);
    printf("Y方向分辨率:%d\n",pBmpInforHead->biYPelsPerMeter);
    printf("使用的颜色数:%u\n",pBmpInforHead->biClrUsed);
    printf("重要颜色数:%u\n",pBmpInforHead->biClrImportant);
}




int main(int argc, const char * argv[]) {
    
    char * filePath = "/Users/西博尔/Desktop/bmp图片/QQ图片20170830184242.bmp"; //到时候图片路径自己更换

    
    BITMAPFILEHEADER   fileHeader;
    BITMAPINFOHEADER infoHeader;
    

    FILE* pfile;
    pfile = fopen(filePath, "rb");
    if(pfile == NULL){
        printf("打开bmp失败!\n");
        return -1;
    }
    int dest_fd ;
    dest_fd = open("NEW.bmp" , O_RDWR | O_CREAT|O_TRUNC , 0777);

    
    
    
    
    
    if(pfile!=NULL)
    {
 
        
        //从文件里读取信息
        fread(&fileHeader, sizeof(fileHeader), 1, pfile);
        fread(&infoHeader, sizeof(infoHeader), 1, pfile);
        
        //解析头信息
        if(fileHeader.bfType != 19778){
            printf("'image.bmp'不是一个bmp格式的文件。\n");
            return -1;
        }
        
        //输出文件信息
        printf("大小:%dkb\n", fileHeader.bfSize);
        printf("尺寸:宽%d 高%d\n", infoHeader.biWidth, infoHeader.biHeight);
        printf("位数:%d\n", infoHeader.biBitCount);
        printf("偏移量:%d\n", fileHeader.bfOffBits);

        
        showBmpHead(&fileHeader);
        printf("\n\n");
        
        //读取位图信息头信息
        showBmpInforHead(&infoHeader);
        printf("\n");
    }
    else
    {
        printf("file open fail!\n");
        return 0;
    }

    
    RGBQUAD * pRgb ;
    
    
    
    int width = infoHeader.biWidth;
    int height = infoHeader.biHeight;
    //分配内存空间把源图存入内存
    int l_width   = WIDTHBYTES(width* infoHeader.biBitCount);//计算位图的实际宽度并确保它为32的倍数
    BYTE    *pColorData=(BYTE *)malloc(height*l_width);
//    memset(pColorData,0,height*l_width);
    long nData = height*l_width;
//
//    //把位图数据信息读到数组里
    fread(pColorData,1,nData,pfile);
//
//    //将位图数据转化为RGB数据
    RGBQUAD* dataOfBmp;
    dataOfBmp = (RGBQUAD *)malloc(width*height*sizeof(RGBQUAD));//用于保存各像素对应的RGB数据
//    memset(dataOfBmp,0,width*height*sizeof(RGBQUAD));
//    
//    

    
    
    
    if(infoHeader.biBitCount == 24)//暂时只支持24位
    {

        
        
        write(dest_fd, &fileHeader, sizeof(BITMAPFILEHEADER));
        write(dest_fd,&infoHeader,sizeof(BITMAPINFOHEADER));
        
        
        int k;  
        int index = 0;  
//用xcode写的, 用C编译器, 可能for循环这个位置要报错
        for(int i=0;i<height;i++) {
            for(int j=0;j<width;j++)
            {
                k = i*l_width + j*3;
               
                // 在这里处理像素 , 但是因为设计logo计算很麻烦, 我就不算了, 简单的加了一个横线
                if (100 <i && i < 110&& j > 100 &&j< 200) {
             
                    dataOfBmp[index].rgbRed = 0x1f;
                    dataOfBmp[index].rgbGreen = 0x1f;
                    dataOfBmp[index].rgbBlue = 0x1f;
                    
                    write(dest_fd , &dataOfBmp[index] , 3);
                    
                }
        
                else
                {
                    dataOfBmp[index].rgbRed = pColorData[k+2];
                    dataOfBmp[index].rgbGreen = pColorData[k+1];
                    dataOfBmp[index].rgbBlue = pColorData[k];
                    write(dest_fd , &dataOfBmp[index] , 3);
                }
                
                
                index++;
                
                
            }
        }
        
        close(dest_fd);
        
    }  
    free(dataOfBmp);  
    free(pColorData);  
    printf("\n");
    printf("完成处理\n");

    return 0;
    
}

麻烦的地方就是我对write,fwrite,fread,read 不熟悉,平时很少用,花了很长时间, 针对BMP的图片格式解析也是参考的网上的资料, 毕竟自己也不是研究这块的, 懒得看

bmp格式解析和做加固的时候解析Mach-O感觉一样

1.按照bmp文件格式解析文件
2.把解析出来的数据写到新文件
3.把想修改的数据修改好再写入文件
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,911评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,014评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,129评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,283评论 1 264
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,159评论 4 357
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,161评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,565评论 3 382
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,251评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,531评论 1 292
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,619评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,383评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,255评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,624评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,916评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,199评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,553评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,756评论 2 335

推荐阅读更多精彩内容

  • 个人学习批处理的初衷来源于实际工作;在某个迭代版本有个BS(安卓手游模拟器)大需求,从而在测试过程中就重复涉及到...
    Luckykailiu阅读 4,665评论 0 11
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,081评论 25 707
  • 一、温故而知新 1. 内存不够怎么办 内存简单分配策略的问题地址空间不隔离内存使用效率低程序运行的地址不确定 关于...
    SeanCST阅读 7,756评论 0 27
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,947评论 4 60
  • 她对我说那句话的时候,那一天,我记得天还是很蓝的。湛蓝,像她的名字一样。 我想和她手牵手,她的手小小的也很温暖。每...
    波切某萨伊阅读 199评论 0 0