第14章 位图和位块传输_14.1-14.3 位图基础

14.1 位图基础

(1)位图和图元文件的区别:位图是点阵图形;图元文件是矢量图形

(2)位图的缺点:

  ①受设备相关的影响(如色彩、分辨率、纵横比例)

  ②需要很大的存储空间:如640×480像素,16种颜色(4位),需要640*480*4/8/1024(即150KB);1024×768像素,24位图形需要1024*768*24/8/1024/1024(即2.25MB)。位图的存储空间是由图像大小和它所包含颜色的数目决定。而图元文件的存储空间是由图像的复杂度和它所包含的GDI命令的个数来决定的。

(3)位图的优点:速度快,将位图复制到视频显示器,通常比绘制一个图元文件要快得多。

14.2 位图尺寸

14.2.1 颜色和位图

(1)颜色深度(Color Depth):每个像素需要的位的数目。也称位数(bit-count)或每像素位数(bits per pixel,bpp)。

(2)单色位图:每个像素只有1位,也称为“二级(bitlevel)”或“二色”位图。

(3)位数(n)和所能表示的颜色数目(m): m =2^n

14.2.2 现实世界的设备

(1)CGA和HGC显卡:单色(1位)

(2)EGA:16种颜色(4位)。EGA提供64种颜色的调色板,但应用程序只能选16种)。

①16色位图的色彩编码IRGB(强度—红—绿—蓝)

②EGA把内存分为4个“颜色平面”,分别是强度、红、绿、蓝。而每个像素颜色的定义是分别从这4个平面中取1位出来组合得一个IRGB值,然后将此值做为索引从下列表格中取出相应的RGB颜色。

③IRGB值与RGB颜色值的对应关系


IRGB


RGB颜色


颜色名称


IRGB


RGB颜色


颜色名称


0000


00-00-00



1000


80-80-80


深灰


0001


00-00-80


深蓝


1001


00-00-FF



0010


00-80-00


深绿


1010


00-FF-00


绿


0011


00-80-80


深青


1011


00-FF-FF



0100


80-00-00


深红


1100


FF-00-00



0101


80-00-80


深洋红


1101


FF-00-FF


洋红


0110


80-80-00


深黄


1110


FF-FF-00



0111


C0-C0-C0


浅灰


1111


FF-FF-FF


(3)VGA或SVGA显卡:256种颜色(每个像素用8位,不一定对应具体的颜色),显卡采用的是“调色板查找表”的方式。其中20种是保留颜色,其作236种可以自定义。

(4)全真彩显卡:16位或24位。现在一般用24位。即每个像素用3个字节表示。

14.3 位块传输

14.3.1 几个位块传输函数

(1)BitBlt函数:BitBlt(hdcDst,xDst,yDst,cx,cy,hdcSrc,xSrc,ySrc,dwROP);

  ①从“源”设备环境传输到“目标”设备环境(注意是从DC到DC的传输,源是来自DC而不是资源文件)。

  ②源和目标设备可以相同

  ③最重要限制是两个设备一定要“兼容”,如无法从屏幕的东西blt到打印机DC中。

  ④坐标单位和尺寸是基于逻辑单位的。而图像的尺寸cx和cy是源和目标设备共用的参数。如果当源和设备的逻辑单位不同(即映射模式不同)时,图像会被缩放,相当于StretchBlt函数,但其灵活性不如StretchBlt。

【BitBlt程序】注意由于Win7的Aero特性,标题栏等非客户区会出现毛玻璃效果,从而使该程序不能正常运行!
效果图

/*------------------------------------------------------------
BITBLT.C -- BitBlt Demonstration
(c) Charles Petzold, 1998
------------------------------------------------------------*/
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   PSTR szCmdLine, int iCmdShow)
{
    static TCHAR szAppName[] = TEXT("BitBlt");
    HWND         hwnd;
    MSG          msg;
    WNDCLASSEX     wndclass;
    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.cbSize = sizeof(WNDCLASSEX);
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(NULL, IDI_INFORMATION);
    wndclass.hIconSm = LoadIcon(NULL, IDI_INFORMATION);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = szAppName;
    if (!RegisterClassEx(&wndclass))
    {
        MessageBox(NULL, TEXT("This program requires Windows NT!"),
                   szAppName, MB_ICONERROR);
        return 0;
    }

    hwnd = CreateWindow(szAppName,                  // window class name
                        TEXT("BitBlt Demo"), // window caption
                        WS_OVERLAPPEDWINDOW,        // window style
                        CW_USEDEFAULT,              // initial x position
                        CW_USEDEFAULT,              // initial y position
                        CW_USEDEFAULT,              // initial x size
                        CW_USEDEFAULT,              // initial y size
                        NULL,                       // parent window handle
                        NULL,                       // window menu handle
                        hInstance,                  // program instance handle
                        NULL);                     // creation parameters

    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static int cxClient, cyClient, cxSource, cySource;
    HDC         hdcClient, hdcWindow;
    PAINTSTRUCT ps;
    switch (message)
    {
    case WM_CREATE:
        //cxSource=边框+标题栏中图标按钮的宽度
        cxSource = GetSystemMetrics(SM_CXSIZEFRAME) + GetSystemMetrics(SM_CXSIZE);
        //cySource=边框+标题栏高度
        cySource = GetSystemMetrics(SM_CYSIZEFRAME) + GetSystemMetrics(SM_CYCAPTION);
        return 0;
    case WM_SIZE:
        cxClient = LOWORD(lParam);
        cyClient = HIWORD(lParam);
        return 0;
    case WM_PAINT:
        hdcClient = BeginPaint(hwnd, &ps);
        hdcWindow = GetWindowDC(hwnd); //整个窗口含非客户区的dc

        for (int y = 0; y < cyClient; y += cySource)
            for (int x = 0; x < cxClient; x += cxSource)
            {
                BitBlt(hdcClient, x, y, cxSource, cySource,
                       hdcWindow, 0, 0, SRCCOPY);
            }

        ReleaseDC(hwnd, hdcWindow);
        EndPaint(hwnd, &ps);
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

(2)StretchBlt函数:——拉伸位图

StretchBlt(hdcDst,xDst,yDst,cxDst,cyDst,hdcSrc,xSrc,ySrc,cxSrc,cySrc, dwPOP);

  ①除拉伸外,还可以镜像图像或翻转图像。如将cxSrc或cxDst符号

  ②拉伸模式:SetStreatchBltMode(hdc,iMode)——拉伸或缩小时,像素的复制或合并


模式


说明


BLACKONWHITE

STRETCH_ANDSCANS(默认)


如果两个或多个像素必须结合与一个像素,则进行逻辑与操作。像素都是白是,结果才是白。也就是合并的结果一般给出黑色,只有都是白色是才为白。这对白底黑色图案的单色位图来说比较好。


WHITEONBLACK

STRETCH_ORSCANS


逻辑或运算。当像素都是黑时,才是黑色。也就是合并的结果一般给出白色,只有像素都是黑色是才是黑的。这对黑底白色图像的单色位置比较好。


COLORONCOLOR

STRETCH_DELETESCANS


简单地去掉像素行或列。这对彩色位图常是最佳的方法。


HALFTONE

STRETCH_HALFTONE


结合源的颜色,计算平均目标颜色。一般和半色调色板一起使用(见第16章)

【StretchBlt程序】——注意在Win7下会出现与BitBlt程序一样的问题
效果图

/*------------------------------------------------------------
STRETCH.C -- StretchBlt Demonstration
(c) Charles Petzold, 1998
------------------------------------------------------------*/
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   PSTR szCmdLine, int iCmdShow)
{
    static TCHAR szAppName[] = TEXT("StretchBlt");
    HWND         hwnd;
    MSG          msg;
    WNDCLASSEX     wndclass;
    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.cbSize = sizeof(WNDCLASSEX);
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(NULL, IDI_INFORMATION);
    wndclass.hIconSm = LoadIcon(NULL, IDI_INFORMATION);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = szAppName;
    if (!RegisterClassEx(&wndclass))
    {
        MessageBox(NULL, TEXT("This program requires Windows NT!"),
                   szAppName, MB_ICONERROR);
        return 0;
    }

    hwnd = CreateWindow(szAppName,                  // window class name
                        TEXT("StretchBlt Demo"), // window caption
                        WS_OVERLAPPEDWINDOW,        // window style
                        CW_USEDEFAULT,              // initial x position
                        CW_USEDEFAULT,              // initial y position
                        CW_USEDEFAULT,              // initial x size
                        CW_USEDEFAULT,              // initial y size
                        NULL,                       // parent window handle
                        NULL,                       // window menu handle
                        hInstance,                  // program instance handle
                        NULL);                     // creation parameters

    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static int cxClient, cyClient, cxSource, cySource;
    HDC         hdcClient, hdcWindow;
    PAINTSTRUCT ps;
    switch (message)
    {
    case WM_CREATE:
        //cxSource=边框+标题栏中图标按钮的宽度
        cxSource = GetSystemMetrics(SM_CXSIZEFRAME) + GetSystemMetrics(SM_CXSIZE);
        //cySource=边框+标题栏高度
        cySource = GetSystemMetrics(SM_CYSIZEFRAME) + GetSystemMetrics(SM_CYCAPTION);
        return 0;
    case WM_SIZE:
        cxClient = LOWORD(lParam);
        cyClient = HIWORD(lParam);
        return 0;
    case WM_PAINT:
        hdcClient = BeginPaint(hwnd, &ps);
        hdcWindow = GetWindowDC(hwnd); //整个窗口含非客户区的dc

        StretchBlt(hdcClient, 0, 0, cxClient, cyClient,
                   hdcWindow, 0, 0, cxSource, cySource, SRCCOPY);

        ReleaseDC(hwnd, hdcWindow);
        EndPaint(hwnd, &ps);
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

(3)PatBlt——图案块传输:PatBlt(hdc,x,y,cx,cy,dwROP);

  ①单位都是基于逻辑单位的

  ②该函数没有源句柄,因为源为hdc中的画刷句柄。

  ③PatBlt和FillRect函数比较


应用举例


函数调用的差别


绘制黑色矩形


PatBlt(hdc,x,y,cx,cy,BLCKNESS);


FillRect(hdc,&rect,hBrush); //hBrush为黑色画刷,内部也是通过PatBlt的。


反转矩形颜色


PatBlt(hdc,x,y,cx,cy,DSTINVERT);


InvertRect(hdc,&rect);//内部调用PatBlt

14.3.2 光栅操作ROP

(1)位块传输时要涉及三个图像像素位的操作

  ①源:将源位图拉伸或压缩成目标矩形同样的大小

  ②目标:函数调用前的目标矩形

  ③图案:即目标设备上的画刷,要在横向和纵向上不断重复,直到与目标区域一样大。

(2)支持BitBlt、StretchBlt与PatBlt的光栅操作不同(见MSDN相应的函数说明)

14.3.3 单顶点和逻辑矩形问题——以PatBlt(hdc,x,y,cx,cy,dwROP)为例

(1)GDI绘图函数中,只有BitBlt、PatBlt、StretchBlt是以单个顶点加边长来规定逻辑矩形坐标的。其他的函数都要求左上角和右下角坐标。

(2)不同映射模式下顶点坐标和逻辑矩形的设置

时间: 2024-10-09 23:31:42

第14章 位图和位块传输_14.1-14.3 位图基础的相关文章

第14章 位图和位块传输_14.4 GDI位图对象(1)

14.4.1 创建DDB (1)创建 HBITMAP= CreateBitmap(cx,cy,cPlanes,cBitsPixel,lpBits); 参数 说明 cx,cy 指定位图宽度和高度,单位为像素. cPlanes 颜色平面数目.标准的VGA显卡具有4个连续的颜色平面,每个平面取一个对应位,把它们组合起来就是一个像素.但这样被创建出来的位图被限制为标准的16位. cxBits 每个像素点颜色的位数 lpBits 指向颜色数据数组指针.每行的字节数必须是偶数个字节(不足时以0填充).如果该

MySQL性能调优与架构设计——第 14 章 可扩展性设计之数据切分

第 14 章 可扩展性设计之数据切分 前言 通过 MySQL Replication 功能所实现的扩展总是会受到数据库大小的限制,一旦数据库过于庞大,尤其是当写入过于频繁,很难由一台主机支撑的时候,我们还是会面临到扩展瓶颈.这时候,我们就必须许找其他技术手段来解决这个瓶颈,那就是我们这一章所要介绍恶的数据切分技术. 14.1 何谓数据切分 可能很多读者朋友在网上或者杂志上面都已经多次见到关于数据切分的相关文章了,只不过在有些文章中称之为数据的 Sharding.其实不管是称之为数据的 Shard

MiS603开发板 第十一章 CY7C68013A Slave FIFO回传输

作者:MiS603开发团队 日期:20150911 公司:南京米联电子科技有限公司 论坛:www.osrc.cn 网址:www.milinker.com 网店:http://osrc.taobao.com EAT博客:http://blog.chinaaet.com/whilebreak 博客园:http://www.cnblogs.com/milinker/ MiS603开发板 第十一章 CY7C68013A Slave FIFO回传输 CY7C68013A提供了强大和灵活的外部接口通信方式,

【二代示波器教程】第14章 uCOS-III操作系统版本二代示波器实现

第14章      uCOS-III操作系统版本二代示波器实现 本章教程为大家讲解uCOS-III操作系统版本的二代示波器实现.主要讲解RTOS设计框架,即各个任务实现的功能,任务间的通信方案选择,任务栈,系统栈以及全局变量共享问题.同时,工程调试方法也专门做了说明. 14.1  注意事项(重要必读) 14.2  任务功能划分 14.3  用户任务优先级设置 14.4  全局变量分配,系统堆栈和任务堆栈 14.5  任务间通信和全局变量共享问题 14.6  uCOS-III系统调试 14.7  

IC卡的传输协议(2)-块传输协议T=1续【转】

转自:http://bbs.ednchina.com/BLOG_ARTICLE_172025.HTM (3)容错操作 先来看一下容错的规则定义. * 复位应答后,第一个数据块是由终端发往IC卡的,而且只能是一个I块或S块.      * 若终端不希望使用长度为32Byte的IFSD初始值,则应向IC卡发送一个S块(IFS请求),S块(IFS请求)的PCB应具有值CI以表明是一个改变IFSD的请求.INF域包含一个字节,其值表示在所要求的IFSD的字节数,取值为0x20-0xFE.IC卡应向终端回

IC卡的传输协议(2)-块传输协议T=1【转】

转自:http://bbs.ednchina.com/BLOG_ARTICLE_172024.HTM 2.4 块传输协议T=1 T=1协议中,在TAL和IC卡之间传送的命令.R-APDU和传输控制信息(例如确认信息)由块组成. 以下定义了数据链路层的块帧结构.协议的特殊选项和协议操作(包括错误处理). (1)块帧结构 字符帧的定义同前文的描述.T=1协议下,无须进行逐个字符的检验.块的结构如下所示,包括头域.数据域和尾域3个部分,都为可选项. ● 头域包括3个必选字节:        *用于标识

JavaScript高级程序设计(第三版)学习笔记13、14章

第13章,事件 事件冒泡 IE的事件叫做事件冒泡:由具体到不具体 <!DOCTYPE html> <html> <head> <title>Event Bubbling Example</title> </head> <body> <div id="myDiv">Click Me</div> </body> </html> 如果你单击了<div>

第14章 启动文件详解—零死角玩转STM32-F429系列

第14章     启动文件详解 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/firege 本章参考资料<STM32F4xx 中文参考手册>第十章-中断和事件:表 46. STM32F42xxx 和 STM32F43xxx 的向量表:MDK中的帮助手册—ARM Development Tools:用来查询ARM的汇编指令和编译器相关的指令. 14.1 启动文件简介 启动文件由汇编编写,是

3.30日第八次作业,第14章,采购管理,15章,信息文档和配置管理

3.30日第八次作业,第14章,采购管理,15章,信息文档和配置管理   第14章.采购管理1.采购管理包括哪些过程?(记)P382-383 答:1).编制采购计划.2).编制询价计划.3).询价.招投标.4).供方选择.5).合同管理.6).合同收尾. 2.编制采购计划过程的成果是什么?P386-387 答:1).采购管理计划.2).采购工作说明书. 3.判断:每个采购工作说明书都来自于项目范围基准.P387 答:是的. 4.结合P388页表14-1,工作说明书应该清楚地描述哪些内容?P388