BMP文件读写笔记

8.2 bbappend 文件

append 文件能够添加函数到已有 class 中,而不须求创制3个新
class。它向同名 class 添加 append 文件的文件。供给安装 layer
配置,才能加载到对应的 append 文件。由此需求变更 layer 的配备,添加加载
*.bbappend 文件的安插到 BBFILES 变量。例如:
meta-two/conf/layer.conf

BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
${LAYERDIR}/recipes-*/*/*.bbappend"

今日扩充已部分 first recipe,让它在 build task 前先运行一个 patch
函数。为做相比较,将相应的 recipe 和 append 文件放到
meta-two/recipes-base/first 目录。
meta-two/recipes-base/first/first_0.1.bbappend

python do_patch () {
  bb.note ("first:do_patch")
}

addtask patch before do_build

那会儿若列出 first recipe 的 task 列表,能够看来 patch task。运营 bitbake
first 可看到运营了 patch 和 build。

添加前:

sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ bitbake -c listtasks first
Parsing recipes: 100% |################################################################################| Time: 00:00:00
Parsing of 3 .bb files complete (0 cached, 3 parsed). 3 targets, 0 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies
NOTE: Preparing RunQueue
NOTE: Executing RunQueue Tasks
do_showdata
do_build
do_listtasks
NOTE: Tasks Summary: Attempted 1 tasks of which 0 didn't need to be rerun and all succeeded.

添加 append 文件后:

sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ bitbake -c listtasks first
Parsing recipes: 100% |################################################################################| Time: 00:00:00
Parsing of 3 .bb files complete (0 cached, 3 parsed). 3 targets, 0 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies
NOTE: Preparing RunQueue
NOTE: Executing RunQueue Tasks
do_showdata
do_build
do_listtasks
do_patch
NOTE: Tasks Summary: Attempted 1 tasks of which 0 didn't need to be rerun and all succeeded.

运行 bitbake first 结果:

sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ bitbake first
Parsing recipes: 100% |################################################################################| Time: 00:00:00
Parsing of 3 .bb files complete (0 cached, 3 parsed). 3 targets, 0 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies
NOTE: Preparing RunQueue
NOTE: Executing RunQueue Tasks
NOTE: Tasks Summary: Attempted 2 tasks of which 0 didn't need to be rerun and all succeeded.
sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ cat tmp/work/first-0.1-r1/temp/
log.do_build            log.do_listtasks.20111  run.do_build            run.do_listtasks.20111
log.do_build.20152      log.do_patch            run.do_build.20152      run.do_patch
log.do_listtasks        log.do_patch.20151      run.do_listtasks        run.do_patch.20151
log.do_listtasks.20001  log.task_order          run.do_listtasks.20001  
sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ cat tmp/work/first-0.1-r1/temp/log.task_order 
do_listtasks (20001): log.do_listtasks.20001
do_listtasks (20111): log.do_listtasks.20111
do_patch (20151): log.do_patch.20151
do_build (20152): log.do_build.20152
sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ 

提示:倘诺您愿意,今后就能够创设二个 recipe,使用 confbuild class
和二个 append 文件,运营 patch、configure 和 build 职责。

源代码:

8.1 class 继承

为促成 configure-build 链,那里创办七个 class,该 class 继承
mybuild,并简短添加八个 configure task,让 build task 信赖 configure
task。

meta-two/classes/confbuild.bbclass

inherit mybuild                            (1)

confbuild_do_configure () {                (2)

  echo "running configbuild_do_configure."

}

addtask do_configure before do_build       (3)

EXPORT_FUNCTIONS do_configure              (4)
  1. 以 mybuild class 为基础;
  2. 制造新的函数;
  3. 概念函数的顺序,configre 在 build 以前;
  4. export 刚创制的函数使之可用。

接下来成立 third recipe 使用 confbuild class。
meta-two/recipes-base/third_01.bb

DESCRIPTION = "I am the third recipe"
PR = "r1"
inherit confbuild

那时运转 bitabke third 会执行 configure 和 build task。

sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ bitbake third
Parsing recipes: 100% |######################################################################################################################################| Time: 00:00:00
Parsing of 3 .bb files complete (0 cached, 3 parsed). 3 targets, 0 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies
NOTE: Preparing RunQueue
NOTE: Executing RunQueue Tasks
NOTE: Tasks Summary: Attempted 2 tasks of which 0 didn't need to be rerun and all succeeded.
sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ cat tmp/work/third-01-r1/temp/
log.do_build            log.do_configure        log.task_order          run.do_build.19728      run.do_configure.19726  
log.do_build.19728      log.do_configure.19726  run.do_build            run.do_configure        
sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ cat tmp/work/third-01-r1/temp/log.task_order 
do_configure (19726): log.do_configure.19726
do_build (19728): log.do_build.19728
sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ cat tmp/work/third-01-r1/temp/log.do_configure
DEBUG: Executing shell function do_configure
running configbuild_do_configure.
DEBUG: Shell function do_configure finished
sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ cat tmp/work/third-01-r1/temp/log.do_build
DEBUG: Executing shell function do_build
running mybuild_do_build.
DEBUG: Shell function do_build finished
 1  if (bmpInfoHeader.biBitCount == 24)
 2         {
 3             //3通道, 每个像元占3列
 4             channels = 3;
 5             bmpImg->channels = 3; 
 6              //每个像元占3列,数据块是8位的3倍
 7             bmpImg->imageData = (unsigned char*)malloc(sizeof(unsigned char)*width * 3 * height);
 8             step = channels*width;//每行宽度,字节为单位(只包括有效数据)
 9              //计算空白数据,因为每行的长度只能是4的整数倍,如果不是,则以空白补上
10             offset = (channels*width) % 4;
11             if (offset != 0)
12             {
13                 offset = 4 - offset;
14             }
16             for (i = 0; i < height; i++)
17             {
18                 for (j = 0; j < width; j++)
19                 {
20                     for (k = 0; k < 3; k++) //三个通道分别读取
21                     {
22                         fread(&pixVal, sizeof(unsigned char), 1, pFile);
23                         bmpImg->imageData[(height - 1 - i)*step + j * 3 + k] = pixVal;
24                     }
25                 }
26                 if (offset != 0)
27                 {
28                     for (j = 0; j < offset; j++)
29                     {
30                         fread(&pixVal, sizeof(unsigned char), 1, pFile); //读空白
31                     }
32                 }
33             }
34         }

3.2 BitBake 文档

最实在的本子带有源代码。

在终端中,cd 到 bitbake-$version/doc 目录并举办以下命令,生成
doc/bitbake-user-manual/bitbake-user-manual.html。

make html DOC=bitbake-user-manual

其一文书档案可与本学科并行阅读,在读完本教程后也亟需阅读该文档。

yocto
工程文书档案

也有三个 bitbake 章节。

  1. 成立工程

对于24-位真彩色图像就不应用彩色板,因为位图中的兰德酷路泽GB值就表示了各种象素的水彩。

注意:由于 task 和 recipe 是 BitBake
的底子概念。个人觉得翻译成职责和配方不免有误解之处,因而文中基本不对那四个词做翻译。类似的还有
configure。

2)3-6:整个文件大小。4690 0000,为00009046h=36934。

6.4.1 确认营造进度中的 log

Bitbake 创立1个 tmp/work 目录存放全部的 log 文件。那个 log
文件包罗部分妙不可言的音讯,值得一学。第二遍施行完 bitbake world
,其出口为:

sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ bitbake world
Parsing recipes: 100% |################################################################################| Time: 00:00:00
Parsing of 2 .bb files complete (0 cached, 2 parsed). 2 targets, 0 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies
NOTE: Preparing RunQueue
NOTE: Executing RunQueue Tasks
NOTE: Tasks Summary: Attempted 3 tasks of which 0 didn't need to be rerun and all succeeded.
sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ tree tmp/work/           
tmp/work/
├── first-0.1-r1
│   └── temp
│       ├── log.do_build -> log.do_build.17657
│       ├── log.do_build.17657
│       ├── log.task_order
│       ├── run.do_build -> run.do_build.17657
│       └── run.do_build.17657
└── second-1.0-r1
    ├── second-1.0
    └── temp
        ├── log.do_build -> log.do_build.17659
        ├── log.do_build.17659
        ├── log.do_mypatch -> log.do_mypatch.17656
        ├── log.do_mypatch.17656
        ├── log.task_order
        ├── run.do_build -> run.do_build.17659
        ├── run.do_build.17659
        ├── run.do_mypatch -> run.do_mypatch.17656
        └── run.do_mypatch.17656

那些 log 文件包涵众多可行的新闻,比如 BitBake 怎么着运转,执行 tasks
输出了怎么着。

  1. BitBake layers

特出 BitBake 工程蕴含多少个 layer。日常 layer
包括3个一定大旨,比如基础体系、图像系统等。一些工程得以回顾不断三个构建指标,每一种目的由分裂的
layers 组成。例如,营造贰个带 GUI 组件或不带 GUI 组件的 Linux 发行版本。

Layers 可以被使用、增添、配置,也可能有个别覆盖已有些layers。那很关键,因为它同意依照实际要求重用或自定义。

八个 layers 共同动作是通用的例子,由此我们会添加2个万分的层次到工程。

4)9-10:保留,必须设置为0。


10)29-30:各类像素的位数。有1(单色),4(16色),8(256色),16(64K色,高彩色),24(16M色,真彩色),32(4096M色,增强型真彩色)。一千为0010h=16。

9.1.1 定义全局变量

刚才曾经创办二个空的
local.conf,以后在那些文件加一些变量。比如添加一行:

MYVAR="hello from MYVAR"

typedef   struct   tagBITMAPINFOHEADER{ 
DWO卡宴D   biSize;   //   本结构所占用字节数 
LONGbiWidth;   //   位图的肥瘦,以像素为单位 
LONGbiHeight;   //   位图的冲天,以像素为单位 
WO帕杰罗D   biPlanes;   //   指标设备的级别,必须为1 
WOTucsonD   biBitCount//   每个像素所需的位数,必须是1(双色), 
//   4(16色),8(256色)或24(真彩色)之一 
DWOOdysseyD   biCompression;   //   位图压缩类型,必须是   0(不降价扣), 
//   1(BI_汉兰达LE8压缩类型)或2(BI_RAV4LE4压缩类型)之一 
DWOCR-VD   biSizeImage;   //   位图的大大小小,以字节为单位 
LONGbiXPelsPerMeter;   //   位图水平分辨率,每米像素数 
LONGbiYPelsPerMeter;   //   位图垂直分辨率,每米像素数 
DWOGL450D   biClrUsed;//   位图实际使用的颜料表中的颜色数 
DWO福特ExplorerD   biClrImportant;//   位图体现进度中主要的颜色数 
}   BITMAPINFOHEADER; 

1.1 关于本学科

倘诺你读书本学科,表明您早就知晓 BitBake 是一种恍若 make
的构建筑工程具,重要用于 OpenEmbedded 和 Yocto 工程营造 Linux
发行版本。你只怕也已经发现到 BitBake
的读书曲线有点陡,本文可让那一个曲线变平缓一些。

正文不会告知你 BitBake 的任何,可是会尝试解释使用 BitBake
时用到的一部分基本功用。精通这个基础可援助你起来写自身的 BitBake recipe。

3、彩色板


 

6.3 探索 recipes 和 tasks

当今我们有七个 recipes 可用,可探索一些新的 bitbake
命令选项。大家能够赢得BitBake 运营时 recipes 及其
tasks、控制进度的音讯。

 1 #include "bmp.h"  
 2 #include <stdio.h>
 3 
 4 void main()
 5 {
 6     ClImage* img = clLoadImage("c:/122.bmp");
 7     bool flag = clSaveImage("c:/result.bmp", img);
 8     if (flag)
 9     {
10         printf("save ok... \n");
11     }
12 }

6.1 创建 mybuild class

创立3个例外的 build 函数,并共享。先在 tutorial layer 创造 class,如
meta-tutorial/classes/mybuild.bbclass

addtask build
mybuild_do_build () {

  echo "running mybuild_do_build."

}

EXPORT_FUNCTIONS do_build

在 base.class 中,我们添加了四个 build task,它也是3个简单易行的 shell
函数。mybuild_do 前缀的依据是 class 中 task 定义的标准
classname_do_functionname。

EXPORT_FUNCTIONS 使该 build 函数可被那一个 class
的使用者利用,假设不添加那行,则它不会覆盖 base class 中的 build 函数。

前几天,已可在第四个 recipe 中应用那些 class。

1、bmp文件头

bitbake-layer 命令

通过 bitbake-layer 命令检查新 layer 配置。
第二利用 show-layers 选项,展现该工程的 layers、layers
路径和先行级。那里优先级都以 0,后边会尝试改一下。

sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ bitbake-layers show-layers
layer                 path                                      priority
==========================================================================
meta-tutorial         /home/sunyongfeng/workshop/test/tutorial/build/../meta-tutorial  0
meta-two              /home/sunyongfeng/workshop/test/tutorial/build/../meta-two  0

bitbake-layers 命令还有任何有效的选项,可通过 -h 选项展现。

sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ bitbake-layers -h
usage: bitbake-layers [-h] [-d] [-q] <subcommand> ...

BitBake layers utility

optional arguments:
  -h, --help            show this help message and exit
  -d, --debug           Enable debug output
  -q, --quiet           Print only errors

subcommands:
  <subcommand>
    show-layers         show current configured layers
    add-layer           Add a layer to bblayers.conf
    remove-layer        Remove a layer from bblayers.conf
    show-overlayed      list overlayed recipes (where the same recipe exists
                        in another layer)
    show-recipes        list available recipes, showing the layer they are
                        provided by
    show-appends        list bbappend files and recipe files they apply to
    flatten             flatten layer configuration into a separate output
                        directory.
    show-cross-depends  Show dependencies between recipes that cross layer
                        boundaries.
    layerindex-fetch    Fetches a layer from a layer index along with its
                        dependent layers, and adds them to conf/bblayers.conf.
    layerindex-show-depends
                        Find layer dependencies from layer index.

Use bitbake-layers <subcommand> --help to get help on a specific command

BMP文件的数目依据从文件头起初的先后顺序分为多个部分:

4.2.2 创设文件的有的注意事项

build/conf/bblayers.conf

  • 拉长当前目录到 BBPATH,TOPDI奥迪Q5 被 BitBake 设置为当前工作目录。
  • 起来设置 BBFILES 变量为空,Recipes 在末端会增进。
  • 加上我们 meta-tutorial 的门路到 BBLAYEHighlanderS 变量。当 BitBake
    伊始实行时,它会寻找全体给定的 layer 目录,以便获得任何布置。

meta-tutorial/conf/layer.conf

  • LAYE翼虎DI本田CR-V 是 BitBake 传给其所加载 Layer 的变量。大家添加该路线到
    BBPATH 变量。
  • BBFILES 告诉 BitBake recipes
    在哪,今后大家从未添加任何事物,可是说话大家会转移它。

注意事项。“.=” 和“+=”
以不添加空格、添加空格的方法,将追加值附给二个变量。

conf/bitbake.conf
conf/bibake.conf 蕴涵 一多级我们谈论的变量。

classes/base.bbclass
一个 *.bbclass 文件包涵共享功效。大家的 base.bbclass
包蕴部分我们说话利用的 log 函数,以及3个 buld 职分。
并不是很有用,不过 BitBake 有须要,因为只要没有别的现实工作时,BitBake
暗许需要的。大家随后将改变此功用。

位图数据记录了位图的每三个像素值,记录顺序是在围观行内是从左到右,扫描行之间是从下到上。位图的1个像素值所占的字节数: 
当biBitCount=1时,七个像素占三个字节; 
当biBitCount=4时,一个像素占3个字节; 
当biBitCount=8时,一个像素占一个字节; 
当biBitCount=24时,一个像素占一个字节; 
Windows规定3个扫描行所占的字节数必须是 
4的翻番(即以long为单位),不足的以0填充, 
三个扫描行所占的字节数总括方式: 
DataSizePerLine=   (biWidth*   biBitCount+31)/8;   
//   1个扫描行所占的字节数 
DataSizePerLine=   DataSizePerLine/4*4;   //   字节数必须是4的倍数 
 

6.2 在第一个 recipe 中利用 myclass

此间丰盛3个小目的,在 build 职务前先运维一个 patch 函数,这里须求有的
python 的用法。

基于 bitbake 的命名规范,大家抬高多少个新的 recipe
目录,并在该目录内添加2个 recipe 文件
meta-tutorial/recipes-tutorial/second/second_1.0.bb

DESCRIPTION = "I am he second recipe"
PR = "r1"                       (1)
inherit mybuild                 (2)

def pyfunc(o):                  (3)
    print dir (o)

python do_mypatch () {          (4)
  bb.note ("runnin mypatch")
  pyfunc(d)                     (5)
}

addtask mypatch before do_build (6)
  1. 像 first recipe 那样定义 DESCCR-VIPTION 和 PCR-V;
  2. 继承 mybuild class,让 myclass_do_build 成为默许 build task;
  3. 纯 python 函数 pyfunc 获取一些参数,并基于该入参运维 python dir
    函数;
  4. bitbake python 函数 my_patch 添加并登记成一个 task,该 task 要在
    build 函数前实施。
  5. mypatch 函数调用 pyfunc 函数,并传播全局 bitbake 变量 d。d
    (datastore) 由 bitbake 定义,并一贯可用。
  6. mypatch 函数被登记成二个 task,并要求在 build 函数前实施。

这便是二个应用 python 函数的样例。

小心:函数部分的情节在 bitbake 手册 3.4 节。

7) 19-22:位图宽度,以像素为单位。8000 0000,为00000080h=128。

4.1.1 Layer 目录

Layer 目录包蕴配置、任务和指标描述。常用 meta-‘something’ 命名 Layer
目录。

贰 、位图消息头

3.1 安装 BitBake

设置进程很不难:

  • 添加 bitbake-$version/bin 目录到 PATH
  • 添加 bitbake-$version/lib 目录到 PYTHONPATH

即执行:

export PATH=/path/to/bbtutor/bitbake/bin:$PATH
export PYTHONPATH=/path/to/bbtutor/bitbake/lib:$PYTHONPATH

那基本和 yocto init 脚本一致。yocto init 脚本同时也开创 build
目录,大家将在说话开立。

第②检查和测试是或不是一切寻常、bitbake 是还是不是安装成功。通超过实际践以下 bitbake
命令:

bitbake --version

运作结果应该接近:

BitBake Build Tool Core version 1.27.0

17)(55+0)到(50-1+2^biBitCount):彩色板规范。对于调色板中的每一种表项,用下述方法来描述兰德OdysseyGB的值:

1.3 致谢

感谢 Tritech
给本人时间准备本文书档案。同时谢谢大家在题材跟踪站点告诉的标题与打字与印刷错误。

2)24bit位图读取

7.3 扩展 layer 配置

在 layer 的 layer.conf 文件中,定义优化级和任何配置值。为布局 layer
的优先级,须求添加新的概念到已有的 layer.conf。以
meta-tutorial/conf/layer.conf 早先,添加:

# append layer name to list of configured layers                                                       
BBFILE_COLLECTIONS += "tutorial"                                                                       
# and use name as suffix for other properties                                                          
BBFILE_PATTERN_tutorial = "^${LAYERDIR}/"                                                              
BBFILE_PRIORITY_tutorial = "5" 

运用的变量在 BitBake 使用手册有很好的辨证,这里不重复。

格局应是领略的,那里定义 layer
名,并行使这几个名字做为别的变量的后缀。那种在 BitBake
变量名中使用用户定义的域后缀机制,在 BitBake 的洋洋地点能够观察。

同样的,修改 meta-two/conf/layer.conf:

# append layer name to list of configured layers                                                       
BBFILE_COLLECTIONS += "tutorial"                                                                       
# and use name as suffix for other properties                                                          
BBFILE_PATTERN_tutorial = "^${LAYERDIR}/"                                                              
BBFILE_PRIORITY_tutorial = "5" 

万一这时运作 bitbake-layers show-layers,结果是:

sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ bitbake-layers show-layers     
layer                 path                                      priority
==========================================================================
meta-tutorial         /home/sunyongfeng/workshop/test/tutorial/build/../meta-tutorial  5
meta-two              /home/sunyongfeng/workshop/test/tutorial/build/../meta-two  5
  1. 共享和录取配置

结束近来,我们利用 classes 和 config 文件封装配置和
tasks。不过还有越来越多的办法重用和扩充 tasks 和布局:

  • class 继承
  • bbappend 文件
  • include 文件

为申明什么利用那几个方法,大家将添加 class 到 layer-two,新的 class
将介绍叁个 configure-build 链并利用 class 继承重用现存的 mybuild
class。然后在新的 recipe 中央银行使那个新 class,最终通过 append
方法扩张现有的 recipe。

bmp.cpp

  1. 序言

1)8bit位图读取

9.1.2 访问全局变量

能够在 recipes 或 classes 中走访 MYVAPAJERO 变量。那里开创三个新的 recipes 组
recipes-vars,及一个 recipe myvar。
meta-two/recipes-vars/myvar/myvar_0.1.bb

DESCRIPTION = "Show access to global MYVAR"
PR = "r1"

do_build(){
  echo "myvar_sh: ${MYVAR}"                        (1)
}

python do_myvar_py () {
  print "myvar_py:" + d.getVar('MYVAR', True)      (2)
}

addtask myvar_py before do_build
  1. 在类 bash 语法中做客变量;
  2. 由此全局数据存款和储蓄访问变量。

于今运作 bitbake myvar,检查 tmp
目录的输出,则足以旁观大家真的访问了全局 MYVA福睿斯 变量。

sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ bitbake myvar
Parsing recipes: 100% |################################################################################| Time: 00:00:00
Parsing of 4 .bb files complete (0 cached, 4 parsed). 4 targets, 0 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies
NOTE: Preparing RunQueue
NOTE: Executing RunQueue Tasks
NOTE: Tasks Summary: Attempted 2 tasks of which 0 didn't need to be rerun and all succeeded.
sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ 
sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ cat tmp/work/myvar-0.1-r1/temp/log.task_order 
do_myvar_py (4595): log.do_myvar_py.4595
do_build (4596): log.do_build.4596
sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ cat tmp/work/myvar-0.1-r1/temp/log.do_myvar_py
DEBUG: Executing python function do_myvar_py
myvar_py:hello from MYVAR
DEBUG: Python function do_myvar_py finished
sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ cat tmp/work/myvar-0.1-r1/temp/log.do_build
DEBUG: Executing shell function do_build
myvar_sh: hello from MYVAR
DEBUG: Shell function do_build finished

六、写BMP文件

4.2 最小工程

细微的安排看起来像那样:

bbTutorial/
├── build
│   ├── bitbake.lock
│   └── conf
│       └── bblayers.conf
└── meta-tutorial
    ├── classes
    │   └── base.bbclass
    └── conf
        ├── bitbake.conf
        └── layer.conf

亟需创建那 4 个公文:

  • bblayers.conf
  • base.bbclass
  • bitbake.conf
  • layer.conf

BMP文件格式,是Windows系统中普遍应用的图像文件格式。由于它能够不作任何变换地保留图像像素域的多少,由此变成大家收获原始数据的主要根源。Windows的图形用户界面(graphical
user interfaces)也在它的内建图像子系统GDI中对BMP格式提供了接济。

8.3.1 添加 local.conf 用于引用文件

BitBake 工程平时选拔 bitbake.conf 引用三个放在 build 目录内的 local.conf
文件。local.conf
文件大概带有部分当下营造目的相关的特有装置。典型的样例是 Yocto 的设置。

此间模仿 local.conf 的独立应用,让 bitbake.conf require 引用
local.conf,添加以下内容到 meta-tutorial/conf/bitbake.conf:

require local.conf
include conf/might_exist.conf

设若那时实行创设命令,BitBake 会产生类似以下的错误信息:

sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ bitbake world
ERROR: Traceback (most recent call last):
  File "/home/sunyongfeng/ops-build.test/yocto/poky/bitbake/lib/bb/cookerdata.py", line 175, in wrapped
    return func(fn, *args)
  File "/home/sunyongfeng/ops-build.test/yocto/poky/bitbake/lib/bb/cookerdata.py", line 185, in parse_config_file
    return bb.parse.handle(fn, data, include)
  File "/home/sunyongfeng/ops-build.test/yocto/poky/bitbake/lib/bb/parse/__init__.py", line 107, in handle
    return h['handle'](fn, data, include)
  File "/home/sunyongfeng/ops-build.test/yocto/poky/bitbake/lib/bb/parse/parse_py/ConfHandler.py", line 148, in handle
    statements.eval(data)
  File "/home/sunyongfeng/ops-build.test/yocto/poky/bitbake/lib/bb/parse/ast.py", line 39, in eval
    statement.eval(data)
  File "/home/sunyongfeng/ops-build.test/yocto/poky/bitbake/lib/bb/parse/ast.py", line 61, in eval
    bb.parse.ConfHandler.include(self.filename, s, self.lineno, data, "include required")
  File "/home/sunyongfeng/ops-build.test/yocto/poky/bitbake/lib/bb/parse/parse_py/ConfHandler.py", line 98, in include
    raise ParseError("Could not %(error_out)s file %(fn)s" % vars(), parentfn, lineno)
ParseError: ParseError at /home/sunyongfeng/workshop/test/tutorial/build/../meta-tutorial/conf/bitbake.conf:53: Could not include required file local.conf

ERROR: Unable to parse conf/bitbake.conf: ParseError at /home/sunyongfeng/workshop/test/tutorial/build/../meta-tutorial/conf/bitbake.conf:53: Could not include required file local.conf

加上二个 local.conf 文件到 build 目录可解决此难题。注意 include
语句包括的文本可有可无。

  1. 动用变量

可定义变量并在 recipes 中央银行使,让 BitBake
具有很强的左右逢原。可将可安顿部分使用变量的不二法门编写 recipe,那种 recipe
的用户能够付出那2个将由 recipe 使用的变量值。3个独立的例证是给 recipe
传递额外的铺排或标志。通过科学生运动用变量,不供给编写制定和改动
recipe,因为一些函数只要求一些杰出的参数。

  • bmp文件头(bmp file header)提供文件的格式、大小等新闻
  • 位图消息头(bitmap
    information)提供图像数据的尺码、位平面数、压缩格局、颜色索引等新闻
  • 调色板(color
    palette):可选,如使用索引来代表图像,调色板正是索引与其相应的水彩的映射表
  •  位图数据(bitmap data)固然图像数据啦

正文头阵于本身博客
sunyongfeng.com

1 typedef struct
2 {
3     unsigned short    bfType; //文件类型:0x4D42(十六进制ASCII码'BM'
4     unsigned long    bfSize;//文件大小,字节单位表示
5     unsigned short    bfReserved1;//保留,必须设0
6     unsigned short    bfReserved2;//保留,必须设0
7     unsigned long    bfOffBits;//说明从文件头到实际图像数据之间的偏移量
8 } ClBitMapFileHeader;

5.2 添加二个 recipe 到 tutorial layer

BitBake 要求掌握3个 layer 提供哪些 recipes,可因此编制meta-tutorial/conf/layer.conf 文件,使用通配符告诉 BitBake 加载全部的
recipe:

BBPATH .= ":${LAYERDIR}"
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb"

当今得以采纳从前在 build/conf/bblayers.conf 定义的变量。recipe
文件的壮大名是 .bb,若是咱们通过通配符的章程,只用一行就能够告知 BitBake
加载全数 recipes。

一般而言 recipes 有谈得来的目录,并以 groups
的款型收集在一块儿,也正是说把有关联的 recipes 放在同2个索引。

留意:平日采用 recipes-‘group’ 命令那几个目录,那里 group 名表示三个category 或部分顺序。

后天 BitBake 已经知晓从哪找 recipe,我们得以起来添加第多少个 recipe 了。

按一般的做法,我们成立目录
meta-tutorial/recipes-tutorial/first,并在此创设第四个 recipe。 Recipe
文件也有通用的命超级模特式:{recipe}_{version}.bb

 1     //先写文件类型标识
 2          fileType = 0x4D42;
 3     fwrite(&fileType, sizeof(unsigned short), 1, pFile);
 4      if (bmpImg->channels == 1)//8位,单通道,灰度图  
 5     {      
 6                 //每行字节数
 7         step = bmpImg->width;
 8                //如果step 不是4字节的整数倍,凑整
 9         offset = step % 4;
10         if (offset != 0)
11         {
12             offset = 4 - offset;
13             step += offset;
14         }
15                 //写文件头
16         bmpFileHeader.bfSize = 54 + 256 * 4 + bmpImg->width;
17         bmpFileHeader.bfReserved1 = 0;
18         bmpFileHeader.bfReserved2 = 0;
19         bmpFileHeader.bfOffBits = 54 + 256 * 4;
20         fwrite(&bmpFileHeader, sizeof(ClBitMapFileHeader), 1, pFile);
21                  //写位图信息头
22         bmpInfoHeader.biSize = 40;
23         bmpInfoHeader.biWidth = bmpImg->width;
24         bmpInfoHeader.biHeight = bmpImg->height;
25         bmpInfoHeader.biPlanes = 1;
26         bmpInfoHeader.biBitCount = 8;
27         bmpInfoHeader.biCompression = 0;
28         bmpInfoHeader.biSizeImage = bmpImg->height*step;
29         bmpInfoHeader.biXPelsPerMeter = 0;
30         bmpInfoHeader.biYPelsPerMeter = 0;
31         bmpInfoHeader.biClrUsed = 256;
32         bmpInfoHeader.biClrImportant = 256;
33         fwrite(&bmpInfoHeader, sizeof(ClBitMapInfoHeader), 1, pFile);
34         //写调色板,是一个灰度值序列,长度255
35         quad = (ClRgbQuad*)malloc(sizeof(ClRgbQuad) * 256);
36         for (i = 0; i < 256; i++)
37         {
38             quad[i].rgbBlue = i;
39             quad[i].rgbGreen = i;
40             quad[i].rgbRed = i;
41             quad[i].rgbReserved = 0;
42         }
43         fwrite(quad, sizeof(ClRgbQuad), 256, pFile);
44         free(quad);
45                //写每个像素
46         for (i = bmpImg->height - 1; i > -1; i--)
47         {
48             for (j = 0; j < bmpImg->width; j++)
49             {
50                 pixVal = bmpImg->imageData[i*bmpImg->width + j];
51                 fwrite(&pixVal, sizeof(unsigned char), 1, pFile);
52             }
53                         //写无意义充填字节
54             if (offset != 0)
55             {
56                 for (j = 0; j < offset; j++)
57                 {
58                     pixVal = 0;
59                     fwrite(&pixVal, sizeof(unsigned char), 1, pFile);
60                 }
61             }
62         }
63     }

7.1.1 添加新的 layer 目录

始建3个新的目录叫 meta-two:

sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial$ ls
build  meta-tutorial  meta-two

1)1-2:图像文件标识符。0x4d42=’BM’,表示是Windows扶助的BMP格式。

7.1.3 告诉 BitBake 有新的 layer

编辑 build/conf/bblayers.conf,扩展 BBLAYERS 变量:

BBLAYERS = " \
  ${TOPDIR}/../meta-tutorial \
  ${TOPDIR}/../meta-two \
"

图片 1图片 2

本文译自 A practical guide to
BitBake

11)31-34:压缩表达:有0(不减价扣),1(EscortLE 8,7位智跑LE压缩),2(纳瓦拉LE
4,三位本田UR-VLE压缩,3(Bit田野s,位域存放)。XC60LE简单地说是选择像素数+像素值的不二法门开始展览削减(行程编码)。T408运用的是位域存放格局,用四个字节表示几个像素,位域分配为r5b6g5。图中0300
0000为00000003h=3(那张图纸不存在颜色板)。

4.2.3 BitBake 搜索路径

对此 BitBake 来讲,有许多 BBPATH 非法和文书路径。那注脚要是大家报告
BitBake 探索一些途径时,它会招来 BBPATH。
笔者们添加 TOPDI劲客 和 LAYE凯雷德DICRUISER 到 BBPATH,放在 classes/base.bbclass 或
conf/bitbake.conf 中的任意3个。
自然,大家会添加 meta-tutorial 目录。
编写翻译目录不应含有通用文件。只有像 local.conf
对实际编写翻译是有效的,前面大家会用到 local.conf。

E007 为 07E0h = 0000 0111 1110 0000(二进制),是深橙分量的掩码。

4.1.2 Build 目录

Build 目录是 bitbake 命令被实施的地点。在此间,BitBake
期望能找到其开首配置文件,并将其生成的拥有文件放在那几个目录。

为了让 BitBake 运营时出现有别的不当,大家须求创设贰个 build 目录和贰个layer 目录,并在此存放一些亟需的配置文件。

四、读取BMP文件

2.1.1 Config、tasks 与 recipes

经过一种 BitBake 领域特定语言写 Config、tasks 与
recipes,那种语言包蕴变量与可实施的 shell、python
代码。所以理论上,BitBake 能够进行代码,你也得以用 BitBake
做除创设软件之外的业务,可是并不推荐这么做。

BitBake
是一种营造软件的工具,由此有一部分异样的成效,比如可以定义依赖关系。BitBake
能够化解信赖关系,并将其职分以正确顺序运营。其余,营造软件包常常包罗相同或一般的职责。比如大规模的职责:下载源代码包,解压源代码,跑
configure,跑 make,或简捷的输出 log。Bitbake
提供一种体制,可通过一种可配置的点子,抽象、封装和起用那些效应。

  1. 配置 BitBake

BitBake
能够从此间下载:https://github.com/openembedded/bitbake。选用3个版本的分段,并下载
zip。解压 zip 包,可找到三个 bitbake-$version 目录。

留神:本文使用的 Bitbake 版本是 bitbake-1.22,由此适合本课程的 bitbake
版本应该不止或等于1.22。
留意:译者使用 bitbake-1.27.0,因而文中样例为 1.27.0 版本 bitbake
样例。
提示:要是选取 Yocto,则不要求安装 BitBake,Yocto 源代码本身捆绑了
BitBake。Yocto 须要您 source
一个本子,那一个剧本和我们那里做的平等,安装 BitBake 到我们的条件中。

 

4.1 Bitbake 工程布局

透过 BitBake 工程通过 layers 目录与3个 build 目录组织,layer
目录包蕴配置文件和 meta data。

13)39-42:用象素/米代表的品位分辨率。A00F 0000为0000 0FA0h=伍仟。

8.3 include 文件

BitBake 有两种指令引用文件:

  • include filename,那是一种可选引用,假如 filename 找不到,不会有
    error 爆发;
  • require filename,如果 filename 没找到,会产生 error。

值得提的是,include 和 require 都以在 BBPATH 中钦赐的目录查找
filename。

6)15-18:位图图新闻头长度。

5.3 创立第二个 recipe 和 task

我们的首先个 recipe 只打字与印刷一些 log 音讯。将它坐落 tutorial group,版本为
0.1。所以咱们的第二个 recipe 是:
meta-tutorial/recipes-tutorial/first/first_0.1.bb

DESCRIPTION = "I am the first recipe"
PR = "r1"
do_build () {
  echo "first: some shell script running as build"
}
  • task do_build 覆盖 base.bbclass 中的全局 build task。
  • P帕杰罗 是里面修订数据,在历次修订后应被更新。
  • 设置 description 可表达该 recipe 的用处。

若是上边都做对了,能够通过 bitbake -s 列出可用的 recipes。

sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ bitbake -s
Parsing recipes: 100% |################################################################################| Time: 00:00:00
Parsing of 1 .bb files complete (0 cached, 1 parsed). 1 targets, 0 skipped, 0 masked, 0 errors.
Recipe Name                                    Latest Version         Preferred Version
===========                                    ==============         =================

first                                                 :0.1-r1                          

接下来就能够举行 bitbake first 编译 first 组件。

sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ bitbake first
Parsing recipes: 100% |################################################################################| Time: 00:00:00
Parsing of 1 .bb files complete (0 cached, 1 parsed). 1 targets, 0 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies
NOTE: Preparing RunQueue
NOTE: Executing RunQueue Tasks
NOTE: Tasks Summary: Attempted 1 tasks of which 0 didn't need to be rerun and all succeeded.

现今检讨 tmp/work/first-0.1-r1/temp 目录,里面有部分妙不可言的公文:

sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ ls -al tmp/work/first-0.1-r1/temp/
total 20
drwxrwxr-x 2 sunyongfeng sunyongfeng 4096 10月 20 11:19 .
drwxrwxr-x 3 sunyongfeng sunyongfeng 4096 10月 20 11:19 ..
lrwxrwxrwx 1 sunyongfeng sunyongfeng   18 10月 20 11:19 log.do_build -> log.do_build.17314
-rw-rw-r-- 1 sunyongfeng sunyongfeng  123 10月 20 11:19 log.do_build.17314
-rw-rw-r-- 1 sunyongfeng sunyongfeng   37 10月 20 11:19 log.task_order
lrwxrwxrwx 1 sunyongfeng sunyongfeng   18 10月 20 11:19 run.do_build -> run.do_build.17314
-rwxrwxr-x 1 sunyongfeng sunyongfeng  909 10月 20 11:19 run.do_build.17314

sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ cat tmp/work/first-0.1-r1/temp/log.do_build.17314 
DEBUG: Executing shell function do_build
first: some shell script running as build
DEBUG: Shell function do_build finished
sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ cat tmp/work/first-0.1-r1/temp/log.task_order 
do_build (17314): log.do_build.17314
sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ cat tmp/work/first-0.1-r1/temp/run.do_build
#!/bin/sh

# Emit a useful diagnostic if something fails:
bb_exit_handler() {
    ret=$?
    case $ret in
    0)  ;;
    *)  case $BASH_VERSION in
        "")   echo "WARNING: exit code $ret from a shell command.";;
        *)    echo "WARNING: ${BASH_SOURCE[0]}:${BASH_LINENO[0]} exit $ret from
  "$BASH_COMMAND"";;
        esac
        exit $ret
    esac
}
trap 'bb_exit_handler' 0
set -e
export HOME="/home/sunyongfeng"
export SHELL="/bin/bash"
export LOGNAME="sunyongfeng"
export USER="sunyongfeng"
export PATH="/home/sunyongfeng/ops-build.test/yocto/poky/scripts:/home/sunyongfeng/ops-build.test/yocto/poky/bitbake/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin"
export TERM="linux"
do_build() {
  echo "first: some shell script running as build"

}

cd '/home/sunyongfeng/workshop/test/tutorial/build'
do_build

# cleanup
ret=$?
trap '' 0
exit $?
  1. Classes 和 functions

下一步将:

  • 累加一个 class
  • 增加多个使用 class 的 recipe
  • 探索 functions
 1 #pragma once
 2 #include <stdio.h>  
 3 typedef struct
 4 {
 5   //  unsigned short    bfType;  //不单独读就出错 (2bytes)
 6     unsigned long    bfSize; //文件大小,字节单位表示(4bytes)
 7     unsigned short    bfReserved1;//保留,必须设0(2bytes)
 8     unsigned short    bfReserved2;//保留,必须设0(2bytes)
 9     unsigned long    bfOffBits;//说明从文件头到实际图像数据之间的偏移量(4bytes)
10 } ClBitMapFileHeader;
11 
12 //C语言结构体大小计算规则:
13 //1、每个成员的偏移量都必须是当前成员所占内存大小的整数倍如果不是编译器会在成员之间加上填充字节。
14 //2、当所有成员大小计算完毕后,编译器判断当前结构体大小是否是结构体中最宽的成员变量大小的整数倍
15 //如果不是会在最后一个成员后做字节填充。
16 
17 typedef struct
18 {
19     unsigned long  biSize;//说明位图信息头结构所需要的字节数(4bytes)
20     long   biWidth;//列出,像素为单位(4bytes)
21     long   biHeight;//行数,像素为单位(4bytes)
22     unsigned short   biPlanes;//为目标设备说明位面数,其值将总是被设为1(2bytes)
23     unsigned short   biBitCount;//说明比特数/象素,其值为1、4、8、16、24、或32,平时用到的图像绝大部分是24位(真彩色)和8位256色(2bytes)
24     unsigned long  biCompression;//说明图象数据压缩的类型,一般没有没有压缩的类型,一般为0  (4bytes) 
25     unsigned long  biSizeImage;//说明图象的大小,以字节为单位(4bytes) 
26     long   biXPelsPerMeter; //说明水平分辨率,用象素/米表示(4bytes) 
27     long   biYPelsPerMeter;//说明垂直分辨率,用象素/米表示(4bytes) 
28     unsigned long   biClrUsed;//说明位图实际使用的彩色表中的颜色索引数(设为0的话,则说明使用所有调色板项)。(4bytes) 
29     unsigned long   biClrImportant;//说明对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要(4bytes) 
30 } ClBitMapInfoHeader;
31 
32 typedef struct
33 {
34     unsigned char rgbBlue; //该颜色的蓝色分量  
35     unsigned char rgbGreen; //该颜色的绿色分量  
36     unsigned char rgbRed; //该颜色的红色分量  
37     unsigned char rgbReserved; //保留值  
38 } ClRgbQuad;
39 
40 typedef struct
41 {
42     int width;  //宽度,像素单位
43     int height;//高度,像素单位
44     int channels;//通道数
45     unsigned char* imageData;//图像数据
46 }ClImage;
47 
48 //读取文件
49 ClImage* clLoadImage(char* path); 
50 //保存文件
51 bool clSaveImage(char* path, ClImage* bmpImg);

5.1 cache 位置

BitBake 缓存 meta data 在二个索引,即 cache
目录。那会支援加速后边推行的一声令下。

咱俩可通过简单添加二个变量到 bitbake.conf 文件,化解 cache
找不到的题材。由此,大家编辑 meta-tutorial/conf/bitbake.conf
文件,并在头部添加:

CACHE = "${TMPDIR}/cache/default"

添加后运转 bitbake -s 的结果:

sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ bitbake -s
ERROR: no recipe files to build, check your BBPATH and BBFILES?

Summary: There was 1 ERROR message shown, returning a non-zero exit code.

小心:在完结项目中,比如 Yocto,那么些变量已经设置好,我们决不关切。日常cache 路径由不一致的变量组成,在名称中涵盖实际的创设配置,如 debug 或
release。

下一步是加上二个 recipe,必要四个步骤:

  1. 使 bitbake 能够找到 recipes
  2. 写第1个 recipe

【2】CSDN博客:用C语言对BMP举行读写

  1. 译者序

typedef   struct   tagRGBQUAD   { 
BYTErgbBlue;//   紫藤色的亮度(值范围为0-255) 
BYTErgb格林;   //   彩虹色的亮度(值范围为0-255) 
BYTErgbRed;   //   浅绿的亮度(值范围为0-255) 
BYTErgbReserved;//   保留,必须为0 
}   RGBQUAD; 
颜色表中布局数据的个数有biBitCount来规定: 
当biBitCount=1,4,8时,分别有2,16,256个表项; 
当biBitCount=24时,没有颜色表项。 
位图新闻头和颜色表组成位图新闻,BITMAPINFO结构定义如下: 
typedef   struct   tagBITMAPINFO   { 
BITMAPINFOHEADE卡宴   bmiHeader;   //   位图音信头 
RGBQUAD   bmiColors[1];   //   颜色表 
}   BITMAPINFO; 

要是您发现
bug、不了然的章节、打字与印刷错误或任何提议,请邮件告知本人,作者的邮箱是
sunnogo@gmail.com

15)47-50:位图使用的颜色索引数。设为0的话,则表明使用具有调色板项。

6.3.1 显示 recipes 和 tasks 列表

sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ bitbake -s
Parsing recipes: 100% |################################################################################| Time: 00:00:00
Parsing of 2 .bb files complete (0 cached, 2 parsed). 2 targets, 0 skipped, 0 masked, 0 errors.
Recipe Name                                    Latest Version         Preferred Version
===========                                    ==============         =================

first                                                 :0.1-r1                          
second                                                :1.0-r1 

比方想看有个别 recipe 提供哪些 tasks,能够透过
bitbake -c listtasks recipe_name 查看:

sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ bitbake -c listtasks second
Parsing recipes: 100% |################################################################################| Time: 00:00:00
Parsing of 2 .bb files complete (0 cached, 2 parsed). 2 targets, 0 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies
NOTE: Preparing RunQueue
NOTE: Executing RunQueue Tasks
do_showdata
do_build
do_mypatch
do_listtasks
NOTE: Tasks Summary: Attempted 1 tasks of which 0 didn't need to be rerun and all succeeded.

 

7.1 添加3个 layer

透过以下步骤添加3个新的 layer:

  1. 创办多个新的 layer 目录
  2. 创建 layer 配置
  3. 告诉 BitBake 有新的 layer
  4. 添加 recipes 到 layer

 

7.1.2 配置新 layer

添加 meta-two/conf/layer.conf 文件,该公文和 tutorial layer 的同等:

BBPATH .= ":${LAYERDIR}"
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb"

16)51-54:对图象展现有非常重要影响的水彩索引的数额。若是是0,表示都主要。

9.2 本地变量

非凡的 recipe 只包括部分本土变量,这个变量用于其继承的 classes
中的函数设置。

先创建 meta-two/classes/varbuild.bbclass

varbuild_do_build () {
  echo "build with args: ${BUILDARGS}"
}

addtask build

EXPORT_FUNCTIONS do_build

然后在 meta-two/recipes-vars/varbuld/varbuild_0.1.bb 中使用:

DESCRIPTION = "Demonstrate variable usage \
  for setting up a class task"
PR = "r1"

BUILDARGS = "my build arguments"

inherit varbuild

运行 bitbake varbuild,输出的 log 显示 build 职责使用了 recipe
设置的变量值。

sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ bitbake varbuild
Parsing recipes: 100% |################################################################################| Time: 00:00:00
Parsing of 5 .bb files complete (0 cached, 5 parsed). 5 targets, 0 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies
NOTE: Preparing RunQueue
NOTE: Executing RunQueue Tasks
NOTE: Tasks Summary: Attempted 1 tasks of which 0 didn't need to be rerun and all succeeded.
sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ cat tmp/work/varbuild-0.1-r1/temp/log.task_order 
do_build (4760): log.do_build.4760
sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ cat tmp/work/varbuild-0.1-r1/temp/log.do_build
DEBUG: Executing shell function do_build
build with args: my build arguments
DEBUG: Shell function do_build finished
sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ 

那是利用 BitBake的出众格局。通用 task 由 class
定义,比如下载源代码、configure、make 和别的操作,recipe 设置那些 task
所供给的变量。

  1. 附目录树

sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial$ tree ./*
./build
├── bitbake.lock
├── conf
│   └── bblayers.conf
└── local.conf
./meta-tutorial
├── classes
│   ├── base.bbclass
│   └── mybuild.bbclass
├── conf
│   ├── bitbake.conf
│   └── layer.conf
└── recipes-tutorial
    ├── first
    │   └── first_0.1.bb
    └── second
        └── second_1.0.bb
./meta-two
├── classes
│   ├── confbuild.bbclass
│   └── varbuild.bbclass
├── conf
│   ├── bitbake.conf
│   └── layer.conf
├── recipes-base
│   ├── first
│   │   └── first_0.1.bbappend
│   └── third
│       └── third_01.bb
└── recipes-vars
    ├── myvar
    │   └── myvar_0.1.bb
    └── varbuild
        └── varbuild_0.1.bb

14 directories, 17 files
  1. 总结

以上是本课程的持有剧情,多谢您一向看到那里,希望你喜欢。
学学完科目,你应有对 BitBake 的基本概念有中央精通。本学科涉及的剧情有:

  • BitBake 是四个执行 python 和 shell 脚本的引擎;
  • 广大的 BitBake 工程设计与部分私下认可文件的岗位;
  • BitBake 使用的 5 种文件类型(.bb,.bbclass,.bbappend,.conf 和
    include 文件);
  • BitBake 函数和 task,表达什么协会、分组和调用它们;
  • BitBake 变量及其主旨使用方法 。

深谙那一个剧情后,希望你能够初步使用类似 Yocto 的工程,并三番五次深远理解。

4、位图数据**

9.1 全局变量

全局变量能够通过使用者设置,recipe 能够行使。

位图的多个像素值所占的字节数分裂时,各类像素的囤积大小不一,读取位图图像数据时要求对分化的位图选用区别的处理,六位和2多少人为常用的二种档次,那里首先介绍,1个人的二值图叁个字节表示八个像素音信,必要经过位运算解析出各类像素的值(0或1),通过在对5人位图读取方法开展扩充达成。

4.2.1 需求的安顿文件

先是描述需要的公文,然后简单表达其内容。

build/conf/bblayers.conf,BitBake 在其行事目录(即 build
目录)期望找到的首先个文件。今后咱们以以下内容创立一个 bblayers.conf:

BBPATH := "${TOPDIR}"
BBFILES ?= ""
BBLAYERS = "/path/to/meta-tutorial"

meta-tutorial/conf/layer.conf,每种 layer 必要3个 conf/layer.conf
文件。今后大家以以下内容创制它:

BBPATH .= ":${LAYERDIR}"
BBFILES += ""

meta-tutorial/classes/base.bbclass
meta-tutorial/conf/bitbake.conf
现行反革命,这么些文件能够从 BitBake 安装目录中取得。这几个文件位于文件夹
bitbake-$version/conf 和 bitbake-$version/classes中。只需将它们复制到
tutorial 项目中。

1 typedef struct
2 {
3     unsigned char rgbBlue; //该颜色的蓝色分量  
4     unsigned char rgbGreen; //该颜色的绿色分量  
5     unsigned char rgbRed; //该颜色的红色分量  
6     unsigned char rgbReserved; //保留值  
7 } ClRgbQuad;

首先次运营

创制上述八个布局文件后,在极限 cd 到 build
目录,那是大家的干活目录。我们向来在 build 目录运维 bitbake 命令,以便
bitbake 能够找到呼应的 conf/bblayers.conf 文件。

现在,在 build 目录,不带任何参数运维 bitbake 命令:

bitbake

借使原先的步骤正确,则决定台会输出:

Nothing to do.  Use 'bitbake world' to build everything, or run 'bitbake --help' for usage information.

那没怎么用,不过三个好的开首。

此间介绍二个很有用的下令标志:输出一些 debug 信息。
执行 bitbake -vDD,然后查看其出口,它报告大家多量有关 BitBake
怎么着动作的音讯。

DEBUG: Found bblayers.conf (~/bbTutorial/build/conf/bblayers.conf)
DEBUG: LOAD ~/bbTutorial/build/conf/bblayers.conf
DEBUG: Adding layer ~/bbTutorial/meta-tutorial
DEBUG: LOAD ~/bbTutorial/meta-tutorial/conf/layer.conf
DEBUG: LOAD ~/bbTutorial/meta-tutorial/conf/bitbake.conf
DEBUG: BB configuration INHERITs:0: inheriting ~/bbTutorial/meta-tutorial/classes/base.bbclass
DEBUG: BB ~/bbTutorial/meta-tutorial/classes/base.bbclass: handle(data, include)
DEBUG: LOAD ~/bbTutorial/meta-tutorial/classes/base.bbclass
DEBUG: Clearing SRCREV cache due to cache policy of: clear
DEBUG: Using cache in '~/bbTutorial/build/tmp/cache/local_file_checksum_cache.dat'
DEBUG: Using cache in '~/bbTutorial/build/tmp/cache/bb_codeparser.dat'

你在注意到 BitBake 创设了贰个 bitbake.log 文件和二个 tmp 目录?

sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ ls
bitbake.lock  conf  tmp

提示,全体的样例代码都可从
https://bitbucket.org/a4z/bitbakeguide
获取。本样例在 ch04。

  1. 第一个 recipe

BitBake 必要 recipes 定义要做些什么,今后那里怎么都尚未。
小编们能够透过 bitbake -s 确认运营时怎么着也没做:

sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ bitbake -s
ERROR: no recipe files to build, check your BBPATH and BBFILES?

Summary: There was 1 ERROR message shown, returning a non-zero exit code.
NOTE: Not using a cache. Set CACHE = <directory> to enable.
Recipe Name                                    Latest Version         Preferred Version
===========                                    ==============         =================

sunyongfeng@openswitch-OptiPlex-380:~/workshop/test/tutorial/build$ 

那告诉我们八个消息:

  1. 从没定义任何 cache;
  2. BitBake 真的闲暇可做,只突显了多少个空的 recipe 列表

【3】CSDN博客:BMP格式介绍

2.1 什么是 BitBake

以下内容有助于精通 BitBake:

大抵,BitBake是一个Python程序,它由用户创立的配置驱动,能够为用户钦点的对象实施用户创制的天职,即所谓的配方(recipes)。

壹 、图像文件头

6.4 执行 tasks 或完整创设

稍稍选项可在 recipes 执行 builds 或一定任务时利用。

  • 塑造二个 recipe。使用 bitbade recipe-name 执行该 recipe 的所有
    tasks。
  • 施行3个 task。使用 bitbake -c your-task recipe-name 只运营 recipe
    中的有些 task。
  • 塑造具有 recipe。使用 bitbake world 运营具有 recipes 的有着
    tasks。

能够玩玩那个命令,看会油但是生什么。

3、调色板

1.2 本学科的靶子

本学科学知识展览会示什么创立三个小小的工程,并一步步恢弘,表明 BitBake 怎么样运行。

图片 3图片 4

1.4 反馈

设若你意识 bug、不知情的章节、打字与印刷错误或其余提议, 请使用 issue tracker
https://bitbucket.org/a4z/bitbakeguide/issues,不要求登记。
再者也足以动用本文尾部的 Disqus 评论功效。

  1. BitBake

14)43-46:用象素/米代表的垂直分辨率。A00F 0000为0000 0FA0h=五千。

 1 if (bmpInfoHeader.biBitCount == 8)//256色位图
 2         {
 3             channels = 1;
 4             //每行数据量是4字节整数倍
 5             offset = (channels*width) % 4;
 6             //计算每行需要在有效数据后填充的无意义字节数
 7             if (offset != 0)
 8             {
 9                 offset = 4 - offset;
10             }
11             bmpImg->channels = 1;
12             bmpImg->imageData = (unsigned char*)malloc(sizeof(unsigned char)*width*height);
13             step = channels*width; //每行宽度(字节为单位)
14             quad = (ClRgbQuad*)malloc(sizeof(ClRgbQuad) * 256); 
15             //读取调色板,8位字符调色板包含256种颜色
16             fread(quad, sizeof(ClRgbQuad), 256, pFile);
17             free(quad);
18             //读每个像素的值
19             for (i = 0; i < height; i++)
20             {
21                 for (j = 0; j < width; j++)
22                 {
23                     fread(&pixVal, sizeof(unsigned char), 1, pFile);
24                     // 坐标原点在左下角=》(height - 1 - i)*step+j,通过这个变换坐标原点变为左上角
25                     bmpImg->imageData[(height - 1 - i)*step + j] = pixVal;
26                 }
27                //读行末尾无意义的字节
28                 if (offset != 0)
29                 {
30                     for (j = 0; j < offset; j++)
31                     {
32                         fread(&pixVal, sizeof(unsigned char), 1, pFile);  //读取每行的空字节
33                     }
34                 }
35             }
36         }

贰 、位图新闻头

 

1、写8bit位图

在文件头、位图信息头和调色板(假使局地话)之后,正是位图数据阵列了,

1F00为001Fh = 0000 0000 0001  1111(二进制),是新民主主义革命分量的掩码。

 1       fileType = 0x4D42;
 2     fwrite(&fileType, sizeof(unsigned short), 1, pFile);
 3           //24位,3通道,真彩图  
 4     if (bmpImg->channels == 3)
 5     {
 6         step = bmpImg->channels*bmpImg->width;
 7         offset = step % 4;
 8         if (offset != 0)
 9         {
10             offset = 4 - offset;
11             step += offset;
12         }
13                 //写文件头
14         bmpFileHeader.bfSize = bmpImg->height*step + 54;
15         bmpFileHeader.bfReserved1 = 0;
16         bmpFileHeader.bfReserved2 = 0;
17         bmpFileHeader.bfOffBits = 54;
18         fwrite(&bmpFileHeader, sizeof(ClBitMapFileHeader), 1, pFile);
19                 //写位图信息头
20         bmpInfoHeader.biSize = 40;
21         bmpInfoHeader.biWidth = bmpImg->width;
22         bmpInfoHeader.biHeight = bmpImg->height;
23         bmpInfoHeader.biPlanes = 1;
24         bmpInfoHeader.biBitCount = 24;
25         bmpInfoHeader.biCompression = 0;
26         bmpInfoHeader.biSizeImage = bmpImg->height*step;
27         bmpInfoHeader.biXPelsPerMeter = 0;
28         bmpInfoHeader.biYPelsPerMeter = 0;
29         bmpInfoHeader.biClrUsed = 0;
30         bmpInfoHeader.biClrImportant = 0;
31         fwrite(&bmpInfoHeader, sizeof(ClBitMapInfoHeader), 1, pFile);
32                //写像素每个像素有3个值(R,G,B)
33         for (i = bmpImg->height - 1; i > -1; i--)
34         {
35             for (j = 0; j < bmpImg->width; j++)
36             {
37                 pixVal = bmpImg->imageData[i*bmpImg->width * 3 + j * 3];
38                 fwrite(&pixVal, sizeof(unsigned char), 1, pFile);
39                 pixVal = bmpImg->imageData[i*bmpImg->width * 3 + j * 3 + 1];
40                 fwrite(&pixVal, sizeof(unsigned char), 1, pFile);
41                 pixVal = bmpImg->imageDat,a[i*bmpImg->width * 3 + j * 3 + 2];
42                 fwrite(&pixVal, sizeof(unsigned char), 1, pFile);
43             }
44             if (offset != 0)
45             {
46                 for (j = 0; j < offset; j++)
47                 {
48                     pixVal = 0;
49                     fwrite(&pixVal, sizeof(unsigned char), 1, pFile);
50                 }
51             }
52         }
53     }

5)11-14:从文件伊始成功图数据里面包车型客车偏移量(14+40+4*(2^biBitCount))(在有颜色板的景色下)。4600
0000,为00000046h=70,上边的公文头就是35字=70字节。

将掩码跟像素值实行“与”运算再展开移动操作就能够博得各色分量值。看看掩码,就足以领悟事实上在种种像素值的三个字节15位中,按从高到低取五 、⑥ 、6位分别就是r、g、b分量值。取出分量值后把r、g、b值分别乘以⑧ 、肆 、8就足以补齐第个重量为七个字节,再把那多个字节按rgb组合,放入存储器(同样要反序),就足以转换为24位行业内部BMP格式了。

8)23-26:位图高度,以像素为单位。玖仟 0000,为00000090h=144。

二 、文件相继部分详细描述(以字节文单位):

3)1bit位图(黑白图、二值图)

三 、通过C语言结构体定义表达BMP主要的多个部分

3)7-8:保留,必须设置为0。

bmp.h文件:

代码中,为了从字节的伍人中分析出七个像素值,定义了位运算函数如下:

如,彩色板为00F8 0000 E007 0000 1F00 0000 0000 0000,个中:

 

 1 typedef struct
 2 {
 3     unsigned long  biSize;//说明位图信息头结构所需要的字节数
 4     long   biWidth;//列出,像素为单位
 5     long   biHeight;//行数,像素为单位
 6     unsigned short   biPlanes;//为目标设备说明位面数,其值将总是被设为1
 7     unsigned short   biBitCount;//说明比特数/象素,其值为1、4、8、16、24、或32,平时用到的图像绝大部分是24位(真彩色)和8位256色
 8     unsigned long  biCompression;//说明图象数据压缩的类型,一般没有没有压缩的类型,所以没有此项数据    
 9     unsigned long  biSizeImage;//说明图象的大小,以字节为单位
10     long   biXPelsPerMeter;//说明水平分辨率,用象素/米表示
11     long   biYPelsPerMeter;//说明垂直分辨率,用象素/米表示
12     unsigned long   biClrUsed;//说明位图实际使用的彩色表中的颜色索引数(设为0的话,则说明使用所有调色板项)。
13     unsigned long   biClrImportant;//说明对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要
14 } ClBitMapInfoHeader;

9)27-28:位图的位面数,该值总是1。0100,为0001h=1。

bmp.cpp文件:

【1】百度宏观:BMP文件

 1     if (bmpInfoHeader.biBitCount == 1) {//二值图
 2             channels = 1;
 3             //一个字节存8个像素,除以8向上取整得到字节数
 4             offset = ((int)ceil(width / 8.0)) % 4; 
 5             //求每行末尾的无意义字节数
 6             if (offset != 0)
 7             {
 8                 offset = 4 - offset;
 9             }
10             bmpImg->channels = 1;
11             //存数据的数据块,每个像素用一个字节
12             bmpImg->imageData = (unsigned char*)malloc(sizeof(unsigned char)*width*height);
13             step = channels*width; //每行宽度,字节为单位
14              //读取调色板,二值图像调色板只有两种颜色
15              quad = (ClRgbQuad*)malloc(sizeof(ClRgbQuad) * 2); 
16             fread(quad, sizeof(ClRgbQuad), 2, pFile);
17             free(quad);
18             int w = (int)ceil(width / 8.0);//每行占的字节数
19             //用于临时存储从每个字节读取出来的像素值
20             unsigned char bits[8];
21             //计数器,每行达到图像宽度(width-1),说明后面的bit均为无效,因为最后一个有效字节也只有部分bits是有效的
22             int m = 0;
23             for (i = 0; i < height; i++)
24             {
25                 m = 0;
26                 for (j = 0; j < w; j++)
27                 {
28                     fread(&pixVal, sizeof(unsigned char), 1, pFile);
29                     //获取字符中没一位的值,以一个unsigned char[8]的数组存储
30                     get_bitsofchar(bits, pixVal);
31                     //把每个字节的8位值解析出来,分别存入8个字节
32                     for (int k = 0; k < 8; k++) {
33                         if (m < width) {
34                             //    count[(height - 1 - i)*step + m] = bits[k];
35                             if (bits[k] == 1) { //把值1映射为8位图中的255
36                                 bits[k] = 255;
37                             }
38                             // 坐标原点在左下角=》(height - 1 - i)*step+j,通过这个变换坐标原点变为左上角
39                             bmpImg->imageData[(height - 1 - i)*step + m] = bits[k];
40                         }
41                         m++;
42                     }
43                 }
44                 if (offset != 0)
45                 {
46                     for (j = 0; j < offset; j++)
47                     {
48                         fread(&pixVal, sizeof(unsigned char), 1, pFile);  //读取每行的空字节
49                     }
50                 }
51             }
52             for (int i = 0; i < height; i++) {
53                 for (int j = 0; j < width; j++) {
54                     printf("%d ", bmpImg->imageData[i*width + j]);
55                 }
56                 printf("\n");
57             }
58         }

肆 、图像数据阵列

 

1 typedef struct
2 {
3     int width;  //宽度,像素单位
4     int height;//高度,像素单位
5     int channels;//通道数
6     unsigned char* imageData;//图像数据
7 }ClImage;

2、写24bit位图

 

12)35-38:用字节数表示的位图数据的深浅,该数必须是4的倍数,数值上卓殊:一行所占的字节数×位图中度。00900000为0000捌仟h=80×90×2h=36864。若是位图是2二位,宽为41,高为30,则数值=
(biWidth*biBitCount+31)/32*4*biHeight,即=(41*24+31)/32*4*30=3720

一、简介

 1 //获取一个字节中pos位的值(0或1)
 2 unsigned char  read_bit(char c, int   pos)
 3 {
 4     char   b_mask = 0x01;
 5     b_mask = b_mask << pos;
 6     //字符c和b_mask做位运算如果还是等于b_mask,说明该位为1 
 7     if ((c&b_mask) == b_mask)
 8         return   1;
 9     else
10         return   0;
11 }
12 
13 //将一个Char的所有bit以单个数值(0、1)的形式解析出来
14 void  get_bitsofchar(unsigned char bits[8], char c)
15 {
16     int k = 0;
17     unsigned char t;
18     for (k = 0; k < 8; k++)
19     {
20         bits[k] = read_bit(c, k);
21     }
22     //逆序排列各个bit位——计算机中顺序是从低位向高位排列的
23     for (k = 0; k < 4; k++)
24     {
25         t = bits[k];
26         bits[k] = bits[7 - k];
27         bits[7 - k] = t;
28     }
29 }

【4】博客园:C语言编写BMP读写程序

  1 #include "bmp.h"  
  2 #include <stdio.h>  
  3 #include <stdlib.h>  
  4 #include <math.h>
  5 
  6 //获取一个字节中pos位的值(0或1)
  7 unsigned char  read_bit(char c, int   pos)
  8 {
  9     char   b_mask = 0x01;
 10     b_mask = b_mask << pos;
 11     //字符c和b_mask做位运算如果还是等于b_mask,说明该位为1 
 12     if ((c&b_mask) == b_mask)
 13         return   1;
 14     else
 15         return   0;
 16 }
 17 
 18 //将一个Char的所有bit以单个数值(0、1)的形式解析出来
 19 void  get_bitsofchar(unsigned char bits[8], char c)
 20 {
 21     int k = 0;
 22     unsigned char t;
 23     for (k = 0; k < 8; k++)
 24     {
 25         bits[k] = read_bit(c, k);
 26     }
 27     //逆序排列各个bit位——计算机中顺序是从低位向高位排列的
 28     for (k = 0; k < 4; k++)
 29     {
 30         t = bits[k];
 31         bits[k] = bits[7 - k];
 32         bits[7 - k] = t;
 33     }
 34 }
 35 /*
 36 读取BMP文件,返回一个ClImage对象
 37 */
 38 ClImage* clLoadImage(char* path)
 39 {
 40     ClImage* bmpImg;
 41     FILE* pFile;
 42     unsigned short fileType;
 43     ClBitMapFileHeader bmpFileHeader;
 44     ClBitMapInfoHeader bmpInfoHeader;
 45     int channels = 1;
 46     int width = 0;
 47     int height = 0;
 48     int step = 0;
 49     int offset = 0;
 50     unsigned char pixVal;
 51     ClRgbQuad* quad;
 52     int i, j, k;
 53 
 54     bmpImg = (ClImage*)malloc(sizeof(ClImage));
 55     //pFile = fopen(path, "rb");
 56     fopen_s(&pFile, path, "rb");
 57     if (!pFile)
 58     {
 59         free(bmpImg);
 60         return NULL;
 61     }
 62     //如果不先读取bifType,根据C语言结构体Sizeof运算规则——整体大于部分之和,从而导致读文件错位
 63     fread(&fileType, sizeof(unsigned short), 1, pFile);
 64     if (fileType == 0x4D42)
 65     {
 66         printf("文件类型标识正确! \n");
 67         //读文件头(12bytes,除去bifType)
 68         fread(&bmpFileHeader, sizeof(ClBitMapFileHeader), 1, pFile);
 69         printf("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n");
 70         printf("bmp文件头信息:\n");
 71         printf("文件大小:%d \n", bmpFileHeader.bfSize);
 72         printf("保留字:%d \n", bmpFileHeader.bfReserved1);
 73         printf("保留字:%d \n", bmpFileHeader.bfReserved2);
 74         printf("位图数据偏移字节数:%d \n", bmpFileHeader.bfOffBits);
 75         //读位图信息头40bytes
 76         fread(&bmpInfoHeader, sizeof(ClBitMapInfoHeader), 1, pFile);
 77         printf("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n");
 78         printf("bmp文件信息头\n");
 79         printf("结构体长度:%d \n", bmpInfoHeader.biSize);
 80         printf("位图宽度:%d \n", bmpInfoHeader.biWidth);
 81         printf("位图高度:%d \n", bmpInfoHeader.biHeight);
 82         printf("位图平面数:%d \n", bmpInfoHeader.biPlanes);
 83         printf("颜色位数:%d \n", bmpInfoHeader.biBitCount);
 84         printf("压缩方式:%d \n", bmpInfoHeader.biCompression);
 85         printf("实际位图数据占用的字节数:%d \n", bmpInfoHeader.biSizeImage);
 86         printf("X方向分辨率:%d \n", bmpInfoHeader.biXPelsPerMeter);
 87         printf("Y方向分辨率:%d \n", bmpInfoHeader.biYPelsPerMeter);
 88         printf("使用的颜色数:%d \n", bmpInfoHeader.biClrUsed);
 89         printf("重要颜色数:%d \n", bmpInfoHeader.biClrImportant);
 90         printf("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n");
 91 
 92         //获取图像宽度,高度
 93         width = bmpInfoHeader.biWidth;
 94         height = bmpInfoHeader.biHeight;
 95         bmpImg->width = width;
 96         bmpImg->height = height;
 97 
 98         if (bmpInfoHeader.biBitCount == 1) {//二值图
 99             printf("该文件有调色板,即该位图二值图\n\n");
100             channels = 1;
101             offset = ((int)ceil(width / 8.0)) % 4;  //一个字节存8个像素
102 
103             //求每行末尾的空字节数
104             if (offset != 0)
105             {
106                 offset = 4 - offset;
107             }
108             bmpImg->channels = 1;
109             bmpImg->imageData = (unsigned char*)malloc(sizeof(unsigned char)*width*height);
110             step = channels*width; //每行宽度
111 
112             quad = (ClRgbQuad*)malloc(sizeof(ClRgbQuad) * 2); //读取调色板
113             fread(quad, sizeof(ClRgbQuad), 2, pFile);
114             free(quad);
115 
116 
117             int w = (int)ceil(width / 8.0);//每行占的字节数
118             unsigned char bits[8];
119             int m = 0;
120             for (i = 0; i < height; i++)
121             {
122                 m = 0;
123                 for (j = 0; j < w; j++)
124                 {
125                     fread(&pixVal, sizeof(unsigned char), 1, pFile);
126                     //获取字符中没一位的值,以一个unsigned char[8]的数组存储
127                     get_bitsofchar(bits, pixVal);
128                     //把每个字节的8位值解析出来,分别存入8个字节
129                     for (int k = 0; k < 8; k++) {
130                         if (m < width) {
131                             //    count[(height - 1 - i)*step + m] = bits[k];
132                             if (bits[k] == 1) { //把值1映射为8位图中的255
133                                 bits[k] = 255;
134                             }
135                             // 坐标原点在左下角=》(height - 1 - i)*step+j,通过这个变换坐标原点变为左上角
136                             bmpImg->imageData[(height - 1 - i)*step + m] = bits[k];
137                         }
138                         m++;
139                     }
140                 }
141                 if (offset != 0)
142                 {
143                     for (j = 0; j < offset; j++)
144                     {
145                         fread(&pixVal, sizeof(unsigned char), 1, pFile);  //读取每行的空字节
146                     }
147                 }
148             }
149             for (int i = 0; i < height; i++) {
150                 for (int j = 0; j < width; j++) {
151                     printf("%d ", bmpImg->imageData[i*width + j]);
152                 }
153                 printf("\n");
154             }
155         }
156 
157 
158         else if (bmpInfoHeader.biBitCount == 4) {//十六色位图
159             //一般不用这种格式
160         }
161         else if (bmpInfoHeader.biBitCount == 8)//256色位图
162         {
163             printf("该文件有调色板,即该位图为非真彩色8位256色位图\n\n");
164             channels = 1;
165             offset = (channels*width) % 4;
166             if (offset != 0)
167             {
168                 offset = 4 - offset;
169             }
170             bmpImg->channels = 1;
171             bmpImg->imageData = (unsigned char*)malloc(sizeof(unsigned char)*width*height);
172             step = channels*width; //每行宽度
173 
174             quad = (ClRgbQuad*)malloc(sizeof(ClRgbQuad) * 256); //读取调色板
175             fread(quad, sizeof(ClRgbQuad), 256, pFile);
176             free(quad);
177 
178             for (i = 0; i < height; i++)
179             {
180                 for (j = 0; j < width; j++)
181                 {
182                     fread(&pixVal, sizeof(unsigned char), 1, pFile);
183                     // 坐标原点在左下角=》(height - 1 - i)*step+j,通过这个变换坐标原点变为左上角
184                     bmpImg->imageData[(height - 1 - i)*step + j] = pixVal;
185                 }
186                 if (offset != 0)
187                 {
188                     for (j = 0; j < offset; j++)
189                     {
190                         fread(&pixVal, sizeof(unsigned char), 1, pFile);  //读取每行的空字节
191                     }
192                 }
193             }
194         }
195         //16位高彩色图
196         else if (bmpInfoHeader.biBitCount == 16) {
197             //一般不用这种格式
198         }
199         //真彩色
200         else if (bmpInfoHeader.biBitCount == 24)
201         {
202             printf("该位图为位真彩色\n\n");
203             channels = 3;
204             bmpImg->channels = 3;  //每个像元占3列
205             bmpImg->imageData = (unsigned char*)malloc(sizeof(unsigned char)*width * 3 * height);
206             step = channels*width;
207             offset = (channels*width) % 4;
208             if (offset != 0)
209             {
210                 offset = 4 - offset; //计算空白数据,因为每行的长度只能是4的整数倍,如果不是,则以空白补上
211             }
212 
213             for (i = 0; i < height; i++)
214             {
215                 for (j = 0; j < width; j++)
216                 {
217                     for (k = 0; k < 3; k++) //三个通道分别读取
218                     {
219                         fread(&pixVal, sizeof(unsigned char), 1, pFile);
220                         bmpImg->imageData[(height - 1 - i)*step + j * 3 + k] = pixVal;
221                     }
222                     //kzSetMat(bmpImg->mat, height-1-i, j, kzScalar(pixVal[0], pixVal[1], pixVal[2]));  
223                 }
224                 if (offset != 0)
225                 {
226                     for (j = 0; j < offset; j++)
227                     {
228                         fread(&pixVal, sizeof(unsigned char), 1, pFile); //读空白
229                     }
230                 }
231             }
232         }
233         else if (bmpInfoHeader.biBitCount == 32) { //32位位图--具有透明透明通道
234             //一般不用这种格式
235         }
236     }
237     return bmpImg;
238 }
239 
240 bool clSaveImage(char* path, ClImage* bmpImg)
241 {
242     FILE *pFile;
243     unsigned short fileType;
244     ClBitMapFileHeader bmpFileHeader;
245     ClBitMapInfoHeader bmpInfoHeader;
246     int step;
247     int offset;
248     unsigned char pixVal = '\0';
249     int i, j;
250     ClRgbQuad* quad;
251 
252     //pFile = fopen(path, "wb");
253     fopen_s(&pFile, path, "wb");
254     if (!pFile)
255     {
256         return false;
257     }
258 //
259        fileType = 0x4D42;
260     fwrite(&fileType, sizeof(unsigned short), 1, pFile);
261 
262 
263     if (bmpImg->channels == 3)//24位,通道,彩图  
264     {
265         step = bmpImg->channels*bmpImg->width;
266         offset = step % 4;
267         if (offset != 0)
268         {
269             offset = 4 - offset;
270             step += offset;
271         }
272         /*一个BUG
273         if (offset != 4) {
274             step += 4 - offset;
275         }*/
276         //bmpFileHeader.bfType = 0x4D42;
277         bmpFileHeader.bfSize = bmpImg->height*step + 54;
278         bmpFileHeader.bfReserved1 = 0;
279         bmpFileHeader.bfReserved2 = 0;
280         bmpFileHeader.bfOffBits = 54;
281         fwrite(&bmpFileHeader, sizeof(ClBitMapFileHeader), 1, pFile);
282 
283         bmpInfoHeader.biSize = 40;
284         bmpInfoHeader.biWidth = bmpImg->width;
285         bmpInfoHeader.biHeight = bmpImg->height;
286         bmpInfoHeader.biPlanes = 1;
287         bmpInfoHeader.biBitCount = 24;
288         bmpInfoHeader.biCompression = 0;
289         bmpInfoHeader.biSizeImage = bmpImg->height*step;
290         bmpInfoHeader.biXPelsPerMeter = 0;
291         bmpInfoHeader.biYPelsPerMeter = 0;
292         bmpInfoHeader.biClrUsed = 0;
293         bmpInfoHeader.biClrImportant = 0;
294         fwrite(&bmpInfoHeader, sizeof(ClBitMapInfoHeader), 1, pFile);
295 
296         for (i = bmpImg->height - 1; i > -1; i--)
297         {
298             for (j = 0; j < bmpImg->width; j++)
299             {
300                 pixVal = bmpImg->imageData[i*bmpImg->width * 3 + j * 3];
301                 fwrite(&pixVal, sizeof(unsigned char), 1, pFile);
302                 pixVal = bmpImg->imageData[i*bmpImg->width * 3 + j * 3 + 1];
303                 fwrite(&pixVal, sizeof(unsigned char), 1, pFile);
304                 pixVal = bmpImg->imageData[i*bmpImg->width * 3 + j * 3 + 2];
305                 fwrite(&pixVal, sizeof(unsigned char), 1, pFile);
306             }
307             if (offset != 0)
308             {
309                 for (j = 0; j < offset; j++)
310                 {
311                     pixVal = 0;
312                     fwrite(&pixVal, sizeof(unsigned char), 1, pFile);
313                 }
314             }
315         }
316     }
317 
318     else if (bmpImg->channels == 1)//8位,单通道,灰度图  
319     {
320         step = bmpImg->width;
321         offset = step % 4;
322         if (offset != 0)
323         {
324             offset = 4 - offset;
325             step += offset;
326         }
327         //bmpFileHeader.bfType = 0x4D42;
328         bmpFileHeader.bfSize = 54 + 256 * 4 + bmpImg->width;
329         bmpFileHeader.bfReserved1 = 0;
330         bmpFileHeader.bfReserved2 = 0;
331         bmpFileHeader.bfOffBits = 54 + 256 * 4;
332         fwrite(&bmpFileHeader, sizeof(ClBitMapFileHeader), 1, pFile);
333 
334         bmpInfoHeader.biSize = 40;
335         bmpInfoHeader.biWidth = bmpImg->width;
336         bmpInfoHeader.biHeight = bmpImg->height;
337         bmpInfoHeader.biPlanes = 1;
338         bmpInfoHeader.biBitCount = 8;
339         bmpInfoHeader.biCompression = 0;
340         bmpInfoHeader.biSizeImage = bmpImg->height*step;
341         bmpInfoHeader.biXPelsPerMeter = 0;
342         bmpInfoHeader.biYPelsPerMeter = 0;
343         bmpInfoHeader.biClrUsed = 256;
344         bmpInfoHeader.biClrImportant = 256;
345         fwrite(&bmpInfoHeader, sizeof(ClBitMapInfoHeader), 1, pFile);
346 
347         //调色板是一个灰度图
348         quad = (ClRgbQuad*)malloc(sizeof(ClRgbQuad) * 256);
349         for (i = 0; i < 256; i++)
350         {
351             quad[i].rgbBlue = i;
352             quad[i].rgbGreen = i;
353             quad[i].rgbRed = i;
354             quad[i].rgbReserved = 0;
355         }
356         fwrite(quad, sizeof(ClRgbQuad), 256, pFile);
357         free(quad);
358 
359         for (i = bmpImg->height - 1; i > -1; i--)
360         {
361             for (j = 0; j < bmpImg->width; j++)
362             {
363                 pixVal = bmpImg->imageData[i*bmpImg->width + j];
364                 fwrite(&pixVal, sizeof(unsigned char), 1, pFile);
365             }
366             if (offset != 0)
367             {
368                 for (j = 0; j < offset; j++)
369                 {
370                     pixVal = 0;
371                     fwrite(&pixVal, sizeof(unsigned char), 1, pFile);
372                 }
373             }
374         }
375     }
376     fclose(pFile);
377 
378     return true;
379 }

参考资料:

注:依照C语言中结构体大小的盘算规则(参考:C语言结构体大小总括),结构体变量的Size并不一定是其兼具字段size之和,导致如若直白用四个结构体变量作为读入数据块的器皿,只怕爆发偏差。因而,对文本头的布局体定义去掉了字段bfType,而是在读文件的程序中单独用二个变量读取该音信。

  • 1字节用于深绿分量
  • 1字节用于羊毛白分量
  • 1字节用于革命分量
  • 1字节用于填充符(设置为0,光滑度)

主程序文件:

颜色表结构的概念如下: 

00F8为F800h = 1111 1000 0000 0000(二进制),是灰色分量的掩码。

bmp.h 

其布局定义如下: 
typedef   struct   tagBITMAPFILEHEADER 

WO本田UR-VDbfType;   //   位图像和文字件的项目,必须为BM 
DWOENCORED   bfSize;   //   位图像和文字件的轻重,以字节为单位   
WO帕杰罗DbfReserved1;   //   位图像和文字件保留字,必须为0 
WO奥迪Q3DbfReserved2;   //   位图像和文字件保留字,必须为0 
DWOEscortD   bfOffBits;   //   位图数据的苗头地点,以绝对于位图 
//   文件头的偏移量表示,以字节为单位 
}   BITMAPFILEHEADER; 

0000 总设置为0。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图