多媒体图形图像技术

原创 2004年08月30日 20:24:00

3多媒体图形图像技术

现在我们讲述windows多媒体中最重要,最核心的技术──图形技术。对于Windows的图形图像技术来说,包括基本的GDI绘制对像如点、线、矩形、图像和位图文件,引而广之所有的动画文件都要利用到windows图像图形技术编程。

本章节我们主要讲述Bmp文件实现过程、调色板应用,及一些Bmp图像合成技术,例如:透空技术、Bmp动画技术等。

Bmp文件结构

Bmp文件由以下几个部分组成:文件头、位图信息头、调色板、数据区。下面这张图显示了Bmp文件结构:

Image66.gif

Windows位图显示的必要条件:

我们分析一下一个Windows API函数:

int SetDIBitsToDevice(hdc,uXDest,uYDest,uWidth,uHeight,uXSrc,uYSre,

uStartScan,cScanLines,lpvBits,lpbmi,fuColorUse)

请查看这个函数的第十、十一个参数lpvBits,lpbmi。其中lpvBits指明了指向内存中BMP数据的地址,lpbmi指向一个BITMAPINFO的数据结构,只要有了这两个参数,一个BMP位图就被确定了。大家可以看到绝大多数的Windows图形图像浏览软件所能分析的文件格式,例如jpg、gif、pcx、tif等等,都是先在内存中建一个数据缓冲区,再根据图形图像格式建立一个BITMAPINFO的数据结构,再利用SetDIBitsToDevice函数写到屏幕上。我们下面几个实例,也基本上采用这个方式。

Windows的调色板

Windows的显示设备可以显示出成千上万种颜色,但是,在同一个屏幕上能同时显示的颜色数并不是成千上万种,我们把显示设备分为单色、十六色、二百五十六色、增强色、真彩色,或者是按照显示位区分成1bit,4bit,8bit,16bit,24bit。由于Windows的理论显示数和实际显示数并不相符,因此需要一个方案来解决这个问题,这就要用到调色板这个概念。为何要使用调色板我们在此并不作详细讨论,只是有一点要弄明白,只有十六色和二百五十六色位图才需要调色板。

下面是使用调色板的方法

首先要读入一个位图文件,再判断这个位图文件的颜色数,假如这个文件是十六色或是二百五六色,那么这个文件中必会有一个调色板信息,读取这个调色板信息,将这个调色板信息转为一个LOGPALETTE的结构,根据这个结构生成逻辑调色板,然后每次在要显示位图前,使用SelectPalette函数将逻辑调色板选入设备描述表hDC,再使用RealizePalette函数实现这个调色板,当显示完成后再使用SelectPalette函数,将旧的调色板选择回来,一个调色板调用过程就完成了。

构造windows图像处理类库

我们假设这个类库包含以下功能:

  1. 处理调色板;
    1. .生成逻辑调色板;
    2. 实现调色板;
  2. 处理BMP文件
    1. 读取BMP图像;
    2. 显示图像;
    3. 实现以上“处理调色板”的功能;
  3. 处理FLC动画
    1. 读取FLC动画文件;
    2. 播放参数设置;
    3. 显示图像;
    4. 实现以上“处理调色板”的功能;

通过以上假设我们看到要设计的类库有一些公共特点:

1.都要处理调色板;

2.除了“1”以外,“2”和“3”均包含了windows图像显示的必要条件:结构

BITMAPINFO和一块bitmap数据区。

为此我们首先构造一个处理调色板的类,这个类的实现上述“处理调色板”的功能。为什么要单独处理调色板而不让它附属于“处理BMP文件”或是“处理FLC动画”,其原因是:在大规模多媒体编程中,往往有几十或几百个BMP图像或动画,却只需要一两个调色板,过度泛滥的调色板往往造成版面切换过程中的闪烁,并浪费内存空间,因此要单独处理调色板。

其次我们构造一个处理DIB图像的类:在这个类里,核心为两个参数(结构BITMAPINFO和一块bitmap数据区)和一个调用API函数SetDIBitsToDevice()的显示函数Show()。这个类继承于调色板类,因为处理图像文件必须处理调色板。并成为其他图像文件的基类,因为要处理图像文件必须要有这两个结构和函数。

有了这两个基类后,我们再在这两个基类的基础上构造其他类。

// MyBmp.h: interface for the MyBmp class.
//
//////////////////////////////////////

#if !defined(AFX_MYBMP_H__34151075_C57B_11D1_94F8_0000B431BBA1__INCLUDED_)
#define AFX_MYBMP_H__34151075_C57B_11D1_94F8_0000B431BBA1__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#define FALSERETURN {_lclose(hFile);return 0;}
#define IMAGECOLORS(x,y)(1<<((x)*(y)))
//单行BMP数据的字节数
#define DWORD_WBYTES(x)((((x)+31UL)>>5)<<2)

#define min(a, b)  (((a) < (b)) ? (a) : (b))

#ifdef WIN32
#define BMPDATABYTE
#else
#define BMPDATABYTE _huge
#endif
// #include "test.cpp"

#define PALVERSION      0x0300
#define DIB_STORAGEWIDTH(x) ((x + 3) & ~3)
#define WIDTHBYTES(i)((i+31)/32*4)
#define MAXPALETTE256  /* max. # supported palette entries */
#define MAXLOADFLCNUMBER255

class PALETTE
{
private:
HPALETTE             hOldPal;
protected:
HPALETTE hPal;

public:
PALETTE(){memset(this,0,sizeof(PALETTE));}
~PALETTE(){if(hPal)DeleteObject(hPal);};
HPALETTE CreatePal(BITMAPINFO*);
HPALETTE CreatePal(LPLOGPALETTE Pal);
HPALETTE GetPal(){return hPal;}
UINT SetPal(HDC);
    void ResetPal(HDC);

};


class MYDIB : public PALETTE  
{

protected:
HGLOBALhData;
struct
{
BITMAPINFOHEADERb;
RGBQUADr[256];
}p;

public:
LPBITMAPINFO lpInfo;
LPBITMAPINFOHEADER lpInfoHead;

MYDIB();
~MYDIB();
int Show(HDC,int,int,int,int,int,int,int,int,DWORD);
inline int Show(HDC hDC,int x1,int y1,int x2,int y2,
                                  int x3,int y3,int x4,int y4)
{return Show(hDC,x1,y1,x2,y2,x3,y3,x4,y4,SRCCOPY);}
inline int Show(HDC hDC,int x,int y)
{return Show(hDC,x,y,0,0,0,0,0,0,SRCCOPY);}
inline int Show(HDC hDC)
{return Show(hDC,0,0,0,0,0,0,0,0,SRCCOPY);}

Show(MYDIB*,int,int,int,int,int,int,BYTE,BYTE,BYTE,
                                               BYTE,BYTE,BYTE);
Show(MYDIB*,int,int,int,int,int,int,register 
                                           BYTE,register BYTE);

};

class BMP : public MYDIB 
{

public:
int Open(LPCSTR,int);
int inline Open(LPCSTR name){return Open(name,0);}
};

#endif // !defined(AFX_MYBMP_H__34151075_C57B_11D1_94F8_0000B431BBA1__INCLUDED_)

// MyBmp.cpp: implementation of the MyBmp class.
//
//////////////////////////////////////

#include "stdafx.h"
#include "MyBmp.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////

//////////////////////////////////////
//class PALETTE
//////////////////////////////////////

UINT PALETTE::SetPal(HDC hDC)
{
if(hPal)
{
SelectPalette(hDC,hPal,0);
return RealizePalette(hDC);
}
else return FALSE;
}

void PALETTE::ResetPal(HDC hDC)
{
if(hOldPal)
{
SelectPalette(hDC,hOldPal,0);
            hOldPal=0;
}
   }

HPALETTE PALETTE::CreatePal(LPLOGPALETTE Pal)
{
if(hPal)DeleteObject(hPal);
if(Pal_>palNumEntries<=256)hPal=CreatePalette(Pal);
return hPal;
}

//////////////////////////////////////
//class DIBPALETTE
//////////////////////////////////////

HPALETTE PALETTE::CreatePal(BITMAPINFO* info)
{

struct
{
WORD         palVersion;
WORD         palNumEntries;
PALETTEENTRY palPalEntry[256];
} p;
LPLOGPALETTE Pal=(LPLOGPALETTE)&p;

Pal_>palVersion=0x300;
Pal_>palNumEntries=
/*min*/((WORD)IMAGECOLORS(info_>bmiHeader.biBitCount,1));//,info_>bmiHeader.biClrUsed);

for(int i=0;i<Pal_>palNumEntries;i++)
{
Pal_>palPalEntry[i].peRed=info_>bmiColors[i].rgbRed;
Pal_>palPalEntry[i].peGreen=
                        info_>bmiColors[i].rgbGreen;
Pal_>palPalEntry[i].peBlue=info_>bmiColors[i].rgbBlue;
Pal_>palPalEntry[i].peFlags=PC_NOCOLLAPSE;
}

return PALETTE::CreatePal(Pal);
}

//////////////////////////////////////
// MYDIB Class
//////////////////////////////////////

MYDIB::MYDIB()
{
memset(this,0,sizeof(BMP));
lpInfo=(LPBITMAPINFO)&p;
lpInfoHead=(LPBITMAPINFOHEADER)&p;
}

MYDIB::~MYDIB()
{
if(hData)GlobalFree(hData);
}

int MYDIB::Show(HDC hDC,int x1,int y1,int x2,int y2,int x3,
                             int y3,int x4,int y4,DWORD Rop)
{
if(x2<=0)x2=(int)lpInfoHead_>biWidth+x2;
if(y2<=0)y2=(int)lpInfoHead_>biHeight+y2;
if(x4<=0)x4=(int)lpInfoHead_>biWidth+x4;
if(y4<=0)y4=(int)lpInfoHead_>biHeight+y4;
//if(w_hp)SetPalette(hDC);
BMPDATA* Data=(BMPDATA*)GlobalLock(hData);
//int i=StretchDIBits(hDC,x1,y1,x2,y2,x3,y3,x4,y4,
                                 Data,Info,DIB_RGB_COLORS,Rop);
int i=StretchDIBits(hDC,x1,y1,x2,y2,x3,
        (int)lpInfoHead_>biHeight_y3_y4,x4,y4,Data,lpInfo,
                                          DIB_RGB_COLORS,Rop);
GlobalUnlock(hData);
return i;
}

int MYDIB::Show(MYDIB* dib,int x1,int y1,int x2,int y2,int x3,int y3,
BYTE r1,BYTE g1,BYTE b1,BYTE r2,BYTE g2,BYTE b2)
{
register DWORD c1=(((DWORD)r1)<<16)+(((DWORD)g1)<<8)+b1;
register DWORD c2=(((DWORD)r2)<<16)+(((DWORD)g2)<<8)+b2;
register DWORD c;
register DWORD *rq=(DWORD*)p.r;
if(!dib_>hData)
{
memcpy(dib,this,sizeof(MYDIB));
dib_>lpInfo=(LPBITMAPINFO)&(dib_>p);
dib_>lpInfoHead=(LPBITMAPINFOHEADER)&(dib_>p);
dib_>lpInfoHead_>biWidth=x2+x1;
dib_>lpInfoHead_>biHeight=y2+y1;
DWORD Size=dib_>lpInfoHead_>biWidth
                 *dib_>lpInfoHead_>biHeight
                 *IMAGECOLORS(dib_>lpInfoHead_>biBitCount,1)/8;
dib_>hData=GlobalAlloc(GMEM_FIXED,Size);
}

x2=min(x2,(int)dib_>lpInfoHead_>biWidth _x1);
y2=min(y2,(int)dib_>lpInfoHead_>biHeight_y1);

BMPDATA *Data1=(BMPDATA*)GlobalLock(hData);
BMPDATA *Data2=(BMPDATA*)GlobalLock(dib_>hData);
DWORD w1=DWORD_WBYTES(lpInfoHead_>biWidth
                       *lpInfoHead_>biBitCount);
DWORD w2=DWORD_WBYTES(dib_>lpInfoHead_>biWidth
                       *dib_>lpInfoHead_>biBitCount);
Data1+=(w1*(lpInfoHead_>biHeight_y3_y2)
                          +x3*lpInfoHead_>biBitCount/8);
Data2+=(w2*(dib_>lpInfoHead_>biHeight_y1_y2)
                       +x1*dib_>lpInfoHead_>biBitCount/8);
for(int j=0;j<y2;j++)
{
for(register int i=0;i<x2;i++)
{
c=*(rq+*(Data1+i));
if((c<c1)||(c>c2)||((WORD)c<(WORD)c1)
                      ||((WORD)c>(WORD)c2)
                      ||((BYTE)c<(BYTE)c1)
                ||((BYTE)c>(BYTE)c2))*(Data2+i)=*(Data1+i);
}
Data1+=w1;
Data2+=w2;
}

GlobalUnlock(hData);
GlobalUnlock(dib_>hData);
return TRUE;
}

int MYDIB::Show(MYDIB* dib,int x1,int y1,int x2,int y2,int x3,
                       int y3,register BYTE x,register BYTE y)
{
register BMPDATA d;

if(!dib_>hData)
{
memcpy(dib,this,sizeof(MYDIB));
dib_>lpInfo=(LPBITMAPINFO)&(dib_>p);
dib_>lpInfoHead=(LPBITMAPINFOHEADER)&(dib_>p);
dib_>lpInfoHead_>biWidth=x2+x1;
dib_>lpInfoHead_>biHeight=y2+y1;
DWORD Size=(dib_>lpInfoHead_>biWidth+1)
                  *dib_>lpInfoHead_>biHeight
                  *dib_>lpInfoHead_>biBitCount/8;
                //IMAGECOLORS(dib_>lpInfoHead_>biBitCount,1)/8;
dib_>hData=GlobalAlloc(GMEM_FIXED,Size);
}

x2=min(x2,(int)dib_>lpInfoHead_>biWidth _x1);
y2=min(y2,(int)dib_>lpInfoHead_>biHeight_y1);
BMPDATA *Data1=(BMPDATA*)GlobalLock(hData);
BMPDATA *Data2=(BMPDATA*)GlobalLock(dib_>hData);
DWORD w1=DWORD_WBYTES(lpInfoHead_>biWidth
                              *lpInfoHead_>biBitCount);
DWORD w2=DWORD_WBYTES(dib_>lpInfoHead_>biWidth
                              *dib_>lpInfoHead_>biBitCount);
Data1+=(w1*(lpInfoHead_>biHeight_y3_y2)
              +x3*lpInfoHead_>biBitCount/8);
Data2+=(w2*(dib_>lpInfoHead_>biHeight_y1_y2)
              +x1*dib_>lpInfoHead_>biBitCount/8);

for(int j=0;j<y2;j++)
{
for(register int i=0;i<x2;i++)
{
d=*(Data1+i);
if((d<x)||(d>y))*(Data2+i)=d;
}
Data1+=w1;
Data2+=w2;
}

GlobalUnlock(hData);
GlobalUnlock(dib_>hData);
return TRUE;
}

//////////////////////////////////////
//class bmp
//////////////////////////////////////

int BMP::Open(LPCSTR File,int sty)  //sty:   0:enable hpal  1:disnnable hpal
{
BITMAPFILEHEADER FileHead;
int i;//,j,k;
HFILEhFile;
DWORDuBytes;
DWORDSize;

hFile=_lopen(File,OF_READ);
if(hFile==HFILE_ERROR)return 0;
i=_lread(hFile,&FileHead,sizeof(BITMAPFILEHEADER)); if(i==HFILE_ERROR) FALSERETURN;//goto BMP_FALSE_END; //Type=FileHead.bfType; //读取信息头 i=sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256; _lread(hFile,lpInfoHead,i); if(!sty)CreatePal(lpInfo); uBytes=_llseek(hFile,0,2); if ((FileHead.bfSize)>uBytes) FALSERETURN;//goto BMP_FALSE_END; if(hData)GlobalFree(hData); Size=uBytes_FileHead.bfOffBits; hData=GlobalAlloc(GMEM_FIXED,Size); BMPDATA * Data=(BMPDATA*)GlobalLock(hData); //读取数据 _llseek(hFile,FileHead.bfOffBits,0); for(;_lread(hFile,Data,RBLOCK)==RBLOCK;Data+=RBLOCK); GlobalUnlock(hData); _lclose(hFile); return TRUE; }

在MyBmp.h文件中为了构造BMP框架,我们定义了三个类:class PALETTE

class DIBPALETTE 、class MYDIB 。其中PALETTE是基类。DIBPALETTE继承了类PALETTE,而类MYDIB又继承了类DIBPALETTE。

  • class PALETTE:

在此类中,我们定义了两个成员变量hPal和hOldPal、七个成员函数。这七个成员函数功能如下:其中两个分别是构造函数和析构函数,两个函数CreatePal

(BITMAPINFO*)、CreatePal(LPLOGPALETTE )根据指定参数完成构造调色板的作用,一个函数SetPal(HDC)实现调色板,一个函数ResetPal(HDC)恢复调色板,一个函数GetPal()获得调色板。

  • class MYDIB:

在此类中,我们定义了两个核心成员变量p和hData,其中p是一个自定义结构,它包含一个BMPINFO头信息和一个调色板,hData是指向内存中一块数据的句柄,另外两个参数lpInfo和lpInfoHead实际上是指向结构p的指针。四个成员函数Show()的内核是API函数SetDIBitsToDevice()。它们的功能是根据结构p和句柄hData把图像显示到屏幕上。

  • class BMP:

在此类中,我们只定义了两个成员函数Open,它们的功能是打开一个BMP文件,并将文件内容填入其基类的参数中。前面我们提到过在多媒体编程中需要用公共调色板,但有时也需要用私有调色板,因此在Open函数中第二个参数指定了这个区别,若参数为0则构造自己的hPal,否则自己的hPal无效。

实例分析

在这个实例中,我们将调入一个BMP文件,并把它显示到屏幕上,程序过程如下:

建立一个对话框属性的应用程序,然后是加入光盘中提供的源文件“mybmp.h”和“mybmp.cpp”,在文件“showbmpdlg.h”头加上“#include "mybmp.h"”,在类“CShowbmpDlg”定义中加入成员变量“BMP bmp”,在类“CShowbmpDlg”的成员函数OnInitDialog()中用“bmp.Open("1.bmp")”读取文件“1.bmp”,在OnPaint()中加入以下调色板实现函数和显示函数

bmp.SetPal(dc.m_hDC)

bmp.Show(dc.m_hDC)

bmp.ResetPal(dc.m_hDC)

注意SetPal()和ResetPal()要配对使用,SetPal()用在Show()前,ResetPal()用在Show()后。编译并运行之。

4图像合成

假如要实现一个动画例如一只老鼠从屏幕左边往右边跑过去,一般的书上是这么介绍的:首先做一个老鼠的画片,再画一张黑白老鼠掩模图片。首先用掩模图处理屏幕,再用掩模处理老鼠图片,最后把处理过的老鼠贴到屏幕上,前后要处理三个BitBlt函数。而且这样处理过程会使屏幕出现明显闪烁。要想制止闪烁还要先做一个兼容DC,先把屏幕图片拷贝至兼容DC,再在兼容DC上处理完老鼠后在再拷贝回屏幕。前后要用到五个BitBlt函数。图片比较小还好,若是图片很大,那速度简直就是“去年今日此电脑,人面老鼠相映红,人面不知何处去,老鼠还在慢慢爬”。是否有其他的解决方法呢?

实现透明位图的方式

  1. 最愚蠢的办法:直接在屏幕上逐点用SetPixel函数画图。
  2. 一般的方法:用BitBlt函数作至少三个运算。
  3. 最快的方法:直接写屏。
  4. 性价比最高的办法:直接写数据缓冲区。

四种方式的讨论:

  1. 对于初搞图像处理的程序员来说,似乎逐点画过去的办法是第一选择,然而事实证明这是世界上速度最慢的方法,用它实现的最理想的动画效果是“去年一滴相思泪,今日方流到嘴边”。
  2. BitBlt:前面已介绍过,此处不再介绍。
  3. 直接写屏:Dos下这种方式用得比较多,在windows环境下编程,windows3.1环境下只能加挂WinG才能实现,在win95或NT下可用函数CreateDIBSection()或是使用MicroSoftDirectX函数实现。这种方式我们将出专著介绍。此处不作讨论。
  4. 写数据缓冲区:这个方法对环境要求较小,不需外挂软件,兼容于3.1和95、NT,速度也还可以,它的原理与直接写屏相似,而且可以方便地移植到直接写屏方式中去。我们将在此介绍此方法。

读写数据缓冲区:

大家可能还记得在前面介绍的class MYDIB,里面有两个参数,一个是bmp信息头,一个是bmp数据区,大家是否能想象得到假如修改了bmp数据区的数据,再显示图像会有什么结果?这块数据区,就是我们要使用的数据缓冲区。

透明位图

要想实现透明位图,首先要有两张图片,一张作为源位图,一张作为目的位图,程序员要把源位图贴到目的位图上,并且要指明什么颜色要屏蔽掉,为此,我们在class MYDIB上增加了一个函数Show(MYDIB* dib,int x1,int y1,int x2,int y2,int x3,int y3,BYTE r1, BYTE g1,BYTE b1,BYTE r2,BYTE g2,BYTE b2),这个函数的用法有点类似于BitBlt函数,它的意思为:把己方缓冲区内的数据拷贝到类dib的缓冲区中去,其中从RGB(r1,g1,b1)至RGB(r2,g2,b2)的颜色为透明色,x1、y1、x2、y2、x3、y3为目标坐标、拷贝范围、源坐标,其意义与BitBlt相同。在Show函数的实现过程中,我们首先算出要改变的源数据、目标数据地址,然后分析要拷贝的数据颜色是否属于屏蔽色,假如是屏蔽色,则不拷贝数据,否则拷贝。

另外一种透明位图方式

透明色固然是一种比较简单的实现方式,但是有的时候也需要另外一种实现方式,这就是直接指定颜色索引方式,我们可以指定在调色板中某某号至某某号为透明色。因此,在class MYDIB中再增加一个函数Show(MYDIB* dib,int x1,int y1,int x2,int y2,int x3,int y3,register BYTE x,register BYTE y),这个函数的原理与前一种方式差不多,只是比前一种方式少了四个参数,由以颜色指定透明色改成以颜色索引指定透明色。

透明位图的刷新速度

到底更改数据缓冲区方式的速度快,还是BitBlt速度快?要是BitBlt速度快的话,以前的一番心血岂非成了滚滚长江东逝水,为此我们要用实例分析一下,建立一个名为Tp的基于对话框的程序,加入源程序mybmp.cpp和mybmp.h,在tpdlg.h文件头中加入#include "mybmp.h",在类CTPDlg中加入两个成员变量bmp1和bmp2。在窗口初始化时设置定时器,打开文件“1.bmp”、“2.bmp”,在定时器消息响应过程中完成拷贝和刷新过程,编译并运行程序。我们可以看到一个“AllTime”参数,它显示刷新256张位图需要大约20_21秒左右。现在注释掉定时器消息响应过程中的透底函数bmp1.Show((MYDIB*)&bmp2,0,0,640,480,0,0, 0,0,0,i,i,i),再看刷新256张位图大约需要15_16秒,这是单纯使用函数StretchDIBits所需的时间。可见此处一个透明位图完成时间相当于一点四个BitBlt时间,比照BitBlt方式的三个BitBlt时间(差效果)、五个BitBlt时间(好效果)要好得多。当然,这与直接写屏比又差得多了。

现在再将透底函数换成bmp1.Show((MYDIB*)&bmp2,0,0,640,480,0,0, 0,i),我们不由惊喜地看到现在刷新256张位图的时间为16_17秒,几乎可以认为,缓冲区读写时间已经

可以忽略不计。

图5.3

实例分析

在这个实例中,我们要实现一个动画,背景是一位绝代佳人,前面有一只狗牵着它的宠物跑来跑去。素材需要五张图片,其中背景一张,动画四张。我们分析一下它的实现方式:

在类CMovieDlg中,我们首先用语句BMP bmp[5]定义了五张图片,然后用语句MYDIB temp定义了一个临时图片。在对话框初始化过程函数中分别读入五张位图,设定定时器为一百毫秒,在定时器响应函数中操作过程如下:首先将背景写入临时图片,再将小狗透去白色写入临时图片,最后将临时图片写上屏幕。

Image68.jpg 图5.4

android开发笔记之多媒体—图形图像处理

——图像的两种分类: 位图 例子:单色位图(只有两种颜色(黑白),每一个像素点占一位) 256位图(每一个像素点有256个颜色,每一个像素点需要占一个字节) ...
  • qq_22063697
  • qq_22063697
  • 2016年05月14日 16:22
  • 1137

多媒体信息检索技术简介

多媒体技术和Internet的发展给人们带来巨大的多媒体信息海洋,并进一步导致了超大型多媒体信息库的产生,光凭关键词是很难做到对多媒体信息的描述和检索的,这就需要有一种针对多媒体的有效的检索方式。如何...
  • b06340130
  • b06340130
  • 2013年09月28日 18:59
  • 2047

Android多媒体开发框架

一、Vitamio框架Vitamio 是一款 Android 与 iOS 平台上的全能多媒体开发框架,全面支持硬件解码与 GPU 渲染。Vitamio 凭借其简洁易用的 API 接口赢得了全球众多开发...
  • axi295309066
  • axi295309066
  • 2016年10月02日 16:06
  • 1971

细数Android5.0到Android7.X 多媒体技术新特性

Android 5.0 行为变更媒体播放如果您要实现显示媒体播放状态或传输控件的通知,请考虑使用新的 Notification.MediaStyle 模板,而不是自定义 RemoteViews.Rem...
  • King1425
  • King1425
  • 2017年04月28日 16:23
  • 3140

第 11 章 多媒体技术

音频相关概念      图像相关概念 饱和度:图像的艳丽程度    YUV: 黑白:需要要读取亮度信息 彩色:在读其他的色彩信息    光的三原色:叠加原理 CMY:相减原理    媒...
  • xy88115211
  • xy88115211
  • 2018年01月06日 10:25
  • 38

Android中的图形图像相关(多媒体1)

多媒体:(包含文字 图片 音频 视频) 一、  计算机表示图形的几种方式  图形的大小 = 图片的总像素 * 每个像素的大小 JPG格式:它用有损压缩方式去除冗余的图像和彩色数据,获取得极高的压缩率的...
  • qq_27008179
  • qq_27008179
  • 2016年11月01日 16:32
  • 221

多媒体技术基本概念汇总

多媒体技术这门课中我们将会学到如何使用音频,视频,图片等资源来进行处理。下面的资料是我在大学阶段整理的多媒体技术的基本概念,希望对大家有所帮助。 多媒体技术期末知识点汇总 多媒体技术的主要特性有:(...
  • CHENYUFENG1991
  • CHENYUFENG1991
  • 2015年07月28日 00:05
  • 2147

Android多媒体开发

Android多媒体开发系列文章 Android多媒体开发:录音机 Android多媒体开发:照相机 Android多媒体开发:第三方框架 一、什么是多媒体 多媒体(duō méi tǐ) 的英文单词...
  • axi295309066
  • axi295309066
  • 2016年10月02日 12:38
  • 3302

基于内容的多媒体和跨媒体信息检索技术

信息检索的基本概念   信息检索(IR - Information Retrieval)泛指从包含丰富内容的信息集中找到所需要的或感兴趣的信息或知识的过程,信息检索的主要任务包括对信息项(infor...
  • lskyne
  • lskyne
  • 2013年03月07日 09:56
  • 2341

计算机图形图像处理 实验一

opencv对图像的处理 图像加减乘除运算 图像灰度级变换 图像求反 图像变换 直方图均衡化处理...
  • BabyGoodMorning
  • BabyGoodMorning
  • 2017年04月11日 20:42
  • 646
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:多媒体图形图像技术
举报原因:
原因补充:

(最多只允许输入30个字)