给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.把想修改的数据修改好再写入文件

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值