linux系统下将bmp图片

2013-06-25 16:07:21 zhuxiaowei716 阅读数 5004

转换方法如下:

bmp图片使用bmptoppm。jpg,png,gif都有相应的topnm工具,但我没有试过。

 $bmptoppm pic.bmp > temp1.ppm //生成ppm

 $ppmquant 224 temp1.ppm > temp2.ppm //转换成224颜色

 $pnmnoraw temp2.ppm > logo.ppm //转换成ascii格式

  

logo.ppm就是需要的图像了

2010-05-11 17:28:00 scut1135 阅读数 3851

由于windows中所用头文件"windows.h"在linux下不可用,故自己建立相关的头文件,定义bmp文件的存储结构及格式

代码如下:

 

/* linux_bmp.h*/
/*
 * Copyright (c)2010 Chris Grant
 *
 * Win32 USER structures and API
 */
#include <iostream>
typedef   struct   tagBITMAPFILEHEADER{  
        unsigned   short   bfType;       //2  此处需留意
        unsigned   long    bfSize;         //4                              /*   File   size   in   bytes                     */  
        unsigned   short   bfReserved1;   //2
        unsigned   short   bfReserved2;   //2 
        unsigned   long    bfOffBits;      //4                                  /*   Offset   to   image   data,   bytes   */  
  } __attribute__((packed))BITMAPFILEHEADER,   *PBITMAPFILEHEADER;  //Attention:"__"是两个"_"!  字边界对齐!4字节对齐   知道在linux的gcc下默认的是四字节的
   
typedef   struct   tagBITMAPINFOHEADER{  
        unsigned   long    biSize;              //4                 /*   Header   size   in   bytes            */  
         long         biWidth;               //4              /*   Width   of   image                         */  
         long         biHeight;                  //4          /*   Height   of   image                       */  
        unsigned short   biPlanes;        //2        /*   Number   of   colour   planes       */  
        unsigned short   biBitCount;       //2     /*   Bits   per   pixel                         */  
        unsigned   long biCompression;       //4           /*   Compression   type                     */  
        unsigned   long biSizeImage;    //4                  /*   Image   size   in   bytes               */  
        long   biXPelsPerMeter;     //4
        long   biYPelsPerMeter;      //4  /*   Pixels   per   meter                     */  
        unsigned   long biClrUsed;       //4                   /*   Number   of   colours                   */  
        unsigned   long biClrImportant;       //4         /*   Important   colours                   */  
  } __attribute__((packed))BITMAPINFOHEADER,*PBITMAPINFOHEADER;  
   
typedef   struct   tagRGBQUAD   {  
 unsigned   char   rgbBlue;   /*   Blue   value     */  
 unsigned   char   rgbGreen;   /*   Green   value   */  
 unsigned   char   rgbRed;   /*   Red   value       */  
 unsigned   char   rgbReserved;   /*   Reserved         */  
  }   RGBQUAD;  
    

将其include即可。

 

参考:

1.上篇博客

2. http://m.cnblogs.com/51493/1385324.html

标题: 一个在LINUX下生成BMP的程序

很多人都搞不定内存对齐的问题,最近帮老焦他们写测试程序,用到一个BMP GENERATOR,写了个比较简单的版本,仅针对24位真彩,现把代码公布

#include <iostream>
using namespace std;
typedef long BOOL;
typedef long LONG;
typedef unsigned char BYTE;
typedef unsigned long DWORD;

 

......

......

......
 

 

 3. http://topic.csdn.net/t/20040921/04/3392666.html

c语言实现bmp读写(linux上使用),一个奇怪的错误!欢迎诸位高手指教

 

 我现在需要写一个程序,能够在linux上读写bmp文件,理论上十分简单,但是碰到如下错误,不知道因为什么原因.   
  我在读bmp文件头的时候,发现读出的数据根本不对   
  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_4v1h.asp是msdn上关于bmp的文档的文件头0x00   0x0D共有14byte,   
  文件头的数据结构其定义为   
  typedef   struct   tagBITMAPFILEHEADER   {     
      WORD         bfType;     
      DWORD       bfSize;     
      WORD         bfReserved1;     
      WORD         bfReserved2;     
      DWORD       bfOffBits;     
  }   BITMAPFILEHEADER,   *PBITMAPFILEHEADER;     
    
  由于我需要在linux上运行,不能用WORD和DWORD,我将WORD   换为unsigned   short将DWORD   换为unsigned   int,如下:   
  typedef   struct   {   
        unsigned   short   int   type;                                     
        unsigned   int   size;                                                 
        unsigned   short   int   reserved1;   
        unsigned   short   int   reserved2;   
        unsigned   int   offset;                                             
  }   FILEHEADER;   
  但是该结构将有4+8+4+4+8共28byte(现在cpu的字长一般均为16位)   
  但是我   sizeof(FILEHEADER)则只有16byte,请问这些字节是怎么分配的啊?   
 

 

在Windows上的BITMAPFILEHEADER结构的长度并不是你声称的   4+8+4+4+8   =   28   字节。我在VC6下试了一下,是   2+4+2+2+4   =   14   字节。   
    
  至于你上面定义的   FILEHEADER   结构,由于内存对齐的原因,采取不同的对齐策略会得到不同的长度。在Linux上GCC的默认对齐规则下,各个成员实际占用的内存分别为(括号内为类型长度):4(2)、4(4)、2(2)、2(2)、4(4),所以加起来就是   16   字节。   
    
  根据Windows中的测试结果,BITMAPFILEHEADER采取的内存对齐策略应该是   1   字节或者   2   字节对齐。在Linux中的程序也可采取类似的对齐规则以便统一结构的长度。   
    
  建议你不要倚赖于改变系统的默认的对齐规则的方法。最好在程序中依此读取每个成员(即你的方法二),而不是将整个文件头一次读取到结构中。这样虽然稍微麻烦一点,然而程序的通用性好。

typedef   struct   tagBITMAPFILEHEADER{   
        unsigned   short   bfType;                                   /*   Magic   identifier                         */   
        unsigned   bfSize;                                               /*   File   size   in   bytes                     */   
        unsigned   short   bfReserved1;   
        unsigned   short   bfReserved2;   
        unsigned   bfOffBits;                                         /*   Offset   to   image   data,   bytes   */   
  }   BITMAPFILEHEADER,   *PBITMAPFILEHEADER;   
    
  typedef   struct   tagBITMAPINFOHEADER{   
        unsigned   biSize;                               /*   Header   size   in   bytes             */   
        unsigned   biWidth;                             /*   Width   of   image                         */   
        unsigned   biHeight;                           /*   Height   of   image                       */   
        unsigned   short   biPlanes;               /*   Number   of   colour   planes       */   
        unsigned   short   biBitCount;           /*   Bits   per   pixel                         */   
        unsigned   biCompression;                 /*   Compression   type                     */   
        unsigned   biSizeImage;                     /*   Image   size   in   bytes               */   
        int   biXPelsPerMeter;   
        int   biYPelsPerMeter;                       /*   Pixels   per   meter                     */   
        unsigned   biClrUsed;                         /*   Number   of   colours                   */   
        unsigned   biClrImportant;               /*   Important   colours                   */   
  }   BITMAPINFOHEADER,   *PBITMAPINFOHEADER;   
    
  typedef   struct   tagRGBQUAD   {   
  unsigned   char   rgbBlue; /*   Blue   value     */   
  unsigned   char   rgbGreen; /*   Green   value   */   
  unsigned   char   rgbRed; /*   Red   value       */   
  unsigned   char   rgbReserved; /*   Reserved         */   
  }   RGBQUAD;   
    
    
  我分别用sizeof看他们的大小,分别为16,40,4,后面两个结构就和分别读出的总和一样?就是第一个不同,这是为什么啊?再一个,内存对齐策略是什么意思?

你的结构体肯定是有问题的,因为这种结构肯定是要按四个字节对奇的看看你写的,对不齐就设预留位,看看你写的。   
  typedef   struct   tagBITMAPFILEHEADER   {     
      WORD         bfType;     
      DWORD       bfSize;     
      WORD         bfReserved1;     
      WORD         bfReserved2;     
      DWORD       bfOffBits;     
  }   BITMAPFILEHEADER,   *PBITMAPFILEHEADER;     
  bfType二字节,bfSize四个字节没对齐,你还是找找正确的结构吧。

如果你使用GCC编译器,你可以改变一个结构的对齐方式。比如,想要取消你定义的结构的默认对齐,可以这么做:   
    
  typedef   struct   {   
  unsigned   short   int   type;   
  unsigned   int   size;   
  unsigned   short   int   reserved1;   
  unsigned   short   int   reserved2;   
  unsigned   int   offset;   
  }   __attribute__   ((packed))   FILEHEADER;   
    
  则   sizeof(FILEHEADER)   =   2   +   4   +   2   +   2   +   4   =   14,就变成跟Windows中的类似结构一样的了,你的方法一就能得到正确结果了。但是这样的修改内存对齐的方式在非   Intel   处理器上可能会造成运行错误(在Intel   及其兼容的处理器上运行正常,只是效率稍低些)。   
    
  想了解内存对齐(Memory   Alignment)的概念,你可以在   Google   中以此为关键字进行搜索。

2019-04-13 00:40:59 qq_41447652 阅读数 450

一直用CSDN,觉得这个平台很不错,绝大多数信息都是正确的,一直也想有把自己解决的问题和大家分享,第一次写文章,嘿嘿。希望能帮到有用的人。

本文由完整源码,*************详细注释************,有效果图,有BMP文件格式信息

本来是课后作业,做的过程中遇到问题,网上没找到了,最后琢磨出来了,供大家分享!!!

程序运行环境:Linux操作系统下

程序功能简介:将两幅bmp图像,左右拼接合成一副bmp图像

代码背景:要将一张左眼和右眼的图像,左右合成在一起,生成的新图呈现双(左右)眼试图效果。

                因此文中left.bmp也称为左眼视图,right为右眼视图,file为双眼视图即合成的新图。

 

先将BMP文件信息放着,方便大家查看,

用的纯色图,做的实例拼接,这样能一眼看出没有任何错误:左图红,右图白。合成的图像大小可能看起来不一样,只是因为我上传的时候用的截图。

标题右图——纯白
左图——纯红

效果图:

左右拼接图

源代码如下:

#include<stdio.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>

//54字节文件头信息,bmp图像基本信息,用结构体变量定义
typedef struct
{
	unsigned char blue;  
	unsigned char green;
	unsigned char red;
}Pixel;
typedef struct
{
    //unsigned short bfType;       //下文重新定义此变量,因为bmp文件4字节对齐,此信息为2字节
	unsigned long bfSize;      //整个文件大小包含图像数据与54字节信息                  
	unsigned short bfReserved1;	
	unsigned short bfReserved2;
	unsigned long bfOffBits;
}BmpFileHeader;
typedef struct
{
	unsigned long biSize;
	long biWidth;                    //图像宽度,左右连接应改变此量,下文改变
	long biHeight;                   //图像高度,左右连接不改变此变量
	unsigned short biPlanes;
	unsigned short biBitCount;
	unsigned long biCompression;
	unsigned long biSizeImage;       //文件图像数据大小   
	long biXPelsPerMeter;
	long biYPelsPerMeter;
	unsigned long biClrUsed;
	unsigned long biClrImportant;
}BmpInfoHeader;


//定义BMP文件的路径
const char lfilePath[]={"left.bmp"};
const char rfilePath[]={"right.bmp"};
const char filePath[]={"binoculus.bmp"};

void main()
{
    int fp,fl,fr;                     //文件描述符,对应双眼,左眼,右眼文件
    BmpFileHeader file_head;
    BmpInfoHeader info_head;         //定义一个要使用的结构体量,内容在开头
    unsigned short bfType;           //需要重新定义的头信息
    unsigned char *lineBuf;          //搬运工具,指针
    int i,lineSize;                  //定义的整型变量

    //打开左、右眼文件,只读权限
    //打开失败输出falure!,成功输出successed!
    fl=open(lfilePath,O_RDONLY,0777);        
        if(fl<0)
  	      {
                printf("%s open falure!\n",lfilePath);
              }
	else
	    printf("%s open  lfilePath  successed!\n",lfilePath);

	fr=open(rfilePath,O_RDONLY,0777);		
	    if(fr<0)
	      {
		 printf("%s open falure!\n",rfilePath);
	      }
	else
	    printf("%s open  rfilePath  successed!\n",rfilePath);

    //创建双眼文件,创建和写权限
    fp=open(filePath,O_CREAT|O_WRONLY,0777);    
         if(fp<0)
  	     {
              printf("%s create falure!\n",filePath);       
             }
         else
	   printf("%s create  filePath  successed!\n",filePath);

    //读文件头信息到结构体-----读左眼和右眼文件都可以,本文读左眼
    //读完左眼后fl左眼文件指针指向54字节出,即第一个数据图像像素点。再对fl操作时重此处54开始
    read(fl,&bfType,sizeof(bfType));
    read(fl,&file_head,sizeof(file_head));
    read(fl,&info_head,sizeof(info_head));

    //部分变量改为双眼bmp文件信息
    
    file_head.bfSize=(file_head.bfSize*2-54);
    info_head.biSizeImage=info_head.biSizeImage*2;
    info_head.biWidth=info_head.biWidth*2;


    //将结构体信息(文件头信息)写入目标文件--双眼bmp文件信息
    //写完后fp文件指针指向54字节处,即第一个数据图像像素点。再对fp操作时重此处54开始,
    //即在进行操作为数据信息
    write(fp,&bfType,sizeof(bfType));
    write(fp,&file_head,sizeof(file_head));
    write(fp,&info_head,sizeof(info_head));
	

    //读写数据区文件信息,定义一个指针——搬运数据的工具
    //指针大小为半只眼图的一行
    lineSize=(info_head.biWidth/2)*3*sizeof(unsigned char);   
    lineBuf=(unsigned char*)malloc(lineSize);

	
	//读右眼图像数据文件时需要跳54字节的空间,因为默认重0开始(即指向头信息第一个点)
        //跳过后指向数据区,读出的数据才是正真想要的
	lseek(fr,54,SEEK_SET);

	//每次读写左、右眼文件中的一行,读biHeight次
	for(i=0;i<info_head.biHeight;i++)
	    {             
		read(fl,lineBuf,lineSize);
		write(fp,lineBuf,lineSize);
		read(fr,lineBuf,lineSize);
		write(fp,lineBuf,lineSize);
	    }

	//关闭文件和open配套
   	close(fr);
	close(fl);
	close(fp);
	
	//搭配malloc,释放指针空间
	free(lineBuf);
	printf("assignment successed!!!\n");

}

 

2013-10-06 19:13:00 dianqianguo6739 阅读数 66

今天将之前在win下编好的读取BMP图像功能移植到UNIX下。

碰到的第一个问题是,Linux下的BMP文件头的结构体需要自己重新定义一遍。

第二个问题是,需要搞清楚Linux是32位的还是64位的。因为在定义BMP文件头结构体的时候会定义long型的变量。而在64位系统中long型占8个字节,在32位系统中占4个字节。因此这就会导致文件读取的时候,头信息错位。我的解决办法是将BMP文件头结构体中的long型都换为int型。因为int型在32和64位系统中都是4个字节的。

转载于:https://www.cnblogs.com/shawnpoo/p/3354478.html

2018-05-21 16:11:32 zhangzc1026 阅读数 1661
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

const char filePath[]={"路径"};

typedef struct tagBmpFileHeader //文件头  
{  
    //unsigned short bfType;      //标识该文件为bmp文件,判断文件是否为bmp文件,即用该值与"0x4d42"比较是否相等即可,0x4d42 = 19778  
    unsigned long  bfSize;      //文件大小  
    unsigned short bfReserved1; //预保留位  
    unsigned short bfReserved2; //预保留位  
    unsigned long  bfOffBits;   //图像数据区的起始位置  
}BmpFileHeader;//14字节  
typedef struct tagBmpInfoHeader //信息头  
{  
    unsigned long  biSize;  //图像数据块大小  
    long     biWidth;   //宽度  
    long     biHeight;  //高度  
    unsigned short biPlanes;//为1  
    unsigned short biBitCount; //像素位数,8-灰度图;24-真彩色  
    unsigned long biCompression;//压缩方式  
    unsigned long biSizeImage;  //图像区数据大小  
    long     biXPelsPerMeter;  //水平分辨率,像素每米  
    long     biYPelsPerMeter;  
    unsigned long biClrUsed;   //位图实际用到的颜色数  
    unsigned short biClrImportant;//位图显示过程,重要的颜色数;0--所有都重要  
}BmpInfoHeader;//40字节 

void main()
{
	int fp=-1;
	unsigned short bfType;
	BmpFileHeader file_head;
	BmpInfoHeader info_head;
	fp=open(filePath,O_RDWR,0777);
	if(-1 == fp)
	{
		printf("%s open  failure!!\n",filePath);
	}
	printf("%s open success!\n",filePath);
	
	read(fp,&bfType,sizeof(bfType));
	read(fp,&file_head,sizeof(file_head));
	read(fp,&info_head,sizeof(info_head));
	printf("file head:\n");
	printf("bfType=%x bfSize=%lu ",bfType,file_head.bfSize);
	printf("bfReserved1=%u bfReserved2=%u ",file_head.bfReserved1,file_head.bfReserved2);
	printf("bfOffBits=%lu\n",file_head.bfOffBits);
	
	printf("info head:\n");
	printf("biSize=%lu biWidth=%ld biHeight=%ld ",info_head.biSize,info_head.biWidth,info_head.biHeight);
	printf("biPlanes=%u biBitCount=%u ",info_head.biPlanes,info_head.biBitCount);
	printf("biCompression=%lu biSizeImage=%lu ",info_head.biCompression,info_head.biSizeImage);
	printf("biXPelsPerMeter=%ld biYPelsPerMeter=%ld ",info_head.biXPelsPerMeter,info_head.biYPelsPerMeter);
	printf("biClrUsed=%lu biClrImportant=%u\n",info_head.biClrUsed,info_head.biClrImportant);
	close(fp);
}