EMWI
記事ディレクトリ
序文
JPEGは、フルカラーおよびグレースケール画像の標準的な圧縮方法です。JPEGは、「現実世界」のシーン、線画、漫画、およびその他の非現実的な画像を圧縮するために使用されます。JPEGは不可逆です。つまり、出力画像は入力画像とまったく同じではないため、まったく同じ出力ビットを実現する必要がある場合は、JPEGを使用できません。ただし、一般的な写真画像の場合、認識できる変化なしに非常に優れた圧縮レベルを得ることができます。emWinはJPEG画像表示をサポートしており、外部ストレージ(SDカードなど)からJPEG画像ファイルを直接読み取ってLCDに表示できます。
1.JPEGファイルAPI関数
GUI_JPEG_Draw() 绘制已加载到存储器的 JPEG 文件。
GUI_JPEG_DrawEx() 绘制无需加载到存储器的 JPEG 文件。
GUI_JPEG_DrawScaled() 绘制已加载到存储器的带比例的 JPEG 文件。
GUI_JPEG_DrawScaledEx() 绘制无需加载到存储器的带比例的 JPEG 文件。
GUI_JPEG_GetInfo() 基于已加载到存储器的 JPEG 文件填充 UGI_JPEG_INFO 结构。
GUI_JPEG_GetInfoEx() 基于无需加载到存储器的 JPEG 文件填充 GUI_JPEG_INFO 结构。
2.実験的デモンストレーション
#include "jpegdisplay.h"
#include "EmWinHZFont.h"
#include "GUI.h"
#include "malloc.h"
#include "ff.h"
#include "lcd.h"
#if SYSTEM_SUPPORT_UCOS
#include "includes.h" //ucos ʹÓÃ
#endif
static FIL JPEGFile;
static char jpegBuffer[JPEGPERLINESIZE];
static int JpegGetData(void * p, const U8 ** ppData, unsigned NumBytesReq, U32 Off)
{
static int readaddress=0;
FIL * phFile;
UINT NumBytesRead;
#if SYSTEM_SUPPORT_UCOS
OS_CPU_SR cpu_sr;
#endif
phFile = (FIL *)p;
if (NumBytesReq > sizeof(jpegBuffer))
{
NumBytesReq = sizeof(jpegBuffer);
}
//Òƶ¯Ö¸Õëµ½Ó¦¸Ã¶ÁÈ¡µÄλÖÃ
if(Off == 1) readaddress = 0;
else readaddress=Off;
#if SYSTEM_SUPPORT_UCOS
OS_ENTER_CRITICAL(); //ÁÙ½çÇø
#endif
f_lseek(phFile,readaddress);
//¶ÁÈ¡Êý¾Ýµ½»º³åÇøÖÐ
f_read(phFile,jpegBuffer,NumBytesReq,&NumBytesRead);
#if SYSTEM_SUPPORT_UCOS
OS_EXIT_CRITICAL(); //Í˳öÁÙ½çÇø
#endif
*ppData = (U8 *)jpegBuffer;
return NumBytesRead;//·µ»Ø¶ÁÈ¡µ½µÄ×Ö½ÚÊý
}
//ÔÚÖ¸¶¨Î»ÖÃÏÔʾ¼ÓÔص½RAMÖеÄJPEGͼƬ
//JPEGFileName:ͼƬÔÚSD¿¨»òÕßÆäËû´æ´¢É豸ÖеÄ·¾¶(ÐèÎļþϵͳ֧³Ö£¡)
//mode:ÏÔʾģʽ
// 0 ÔÚÖ¸¶¨Î»ÖÃÏÔʾ£¬ÓвÎÊýx,yÈ·¶¨ÏÔʾλÖÃ
// 1 ÔÚLCDÖмäÏÔʾͼƬ£¬µ±Ñ¡Ôñ´ËģʽµÄʱºò²ÎÊýx,yÎÞЧ¡£
//x:ͼƬ×óÉϽÇÔÚLCDÖеÄxÖáλÖÃ(µ±²ÎÊýmodeΪ1ʱ£¬´Ë²ÎÊýÎÞЧ)
//y:ͼƬ×óÉϽÇÔÚLCDÖеÄyÖáλÖÃ(µ±²ÎÊýmodeΪ1ʱ£¬´Ë²ÎÊýÎÞЧ)
//member: Ëõ·Å±ÈÀýµÄ·Ö×ÓÏî
//denom:Ëõ·Å±ÈÀýµÄ·ÖĸÏî
//·µ»ØÖµ:0 ÏÔʾÕý³£,ÆäËû ʧ°Ü
int displyjpeg(u8 *JPEGFileName,u8 mode,u32 x,u32 y,int member,int denom)
{
u16 bread;
char *jpegbuffer;
char result;
int XSize,YSize;
GUI_JPEG_INFO JpegInfo;
float Xflag,Yflag;
#if SYSTEM_SUPPORT_UCOS
OS_CPU_SR cpu_sr;
#endif
result = f_open(&JPEGFile,(const TCHAR*)JPEGFileName,FA_READ); //´ò¿ªÎļþ
//Îļþ´ò¿ª´íÎó»òÕßÎļþ´óÓÚJPEGMEMORYSIZE
if((result != FR_OK) || (JPEGFile.fsize>JPEGMEMORYSIZE)) return 1;
jpegbuffer=mymalloc(SRAMEX,JPEGFile.fsize); //ÉêÇëÄÚ´æ
if(jpegbuffer == NULL) return 2;
#if SYSTEM_SUPPORT_UCOS
OS_ENTER_CRITICAL(); //ÁÙ½çÇø
#endif
result = f_read(&JPEGFile,jpegbuffer,JPEGFile.fsize,(UINT *)&bread); //¶ÁÈ¡Êý¾Ý
if(result != FR_OK) return 3;
#if SYSTEM_SUPPORT_UCOS
OS_EXIT_CRITICAL(); //Í˳öÁÙ½çÇø
#endif
GUI_JPEG_GetInfo(jpegbuffer,JPEGFile.fsize,&JpegInfo); //»ñÈ¡JEGPͼƬÐÅÏ¢
XSize = JpegInfo.XSize; //»ñÈ¡JPEGͼƬµÄXÖá´óС
YSize = JpegInfo.YSize; //»ñÈ¡JPEGͼƬµÄYÖá´óС
switch(mode)
{
case 0: //ÔÚÖ¸¶¨Î»ÖÃÏÔʾͼƬ
if((member == 1) && (denom == 1)) //ÎÞÐèËõ·Å£¬Ö±½Ó»æÖÆ
{
GUI_JPEG_Draw(jpegbuffer,JPEGFile.fsize,x,y); //ÔÚÖ¸¶¨Î»ÖÃÏÔʾJPEGͼƬ
}else //·ñÔòͼƬÐèÒªËõ·Å
{
GUI_JPEG_DrawScaled(jpegbuffer,JPEGFile.fsize,x,y,member,denom);
}
break;
case 1: //ÔÚLCDÖмäÏÔʾͼƬ
if((member == 1) && (denom == 1)) //ÎÞÐèËõ·Å£¬Ö±½Ó»æÖÆ
{
//ÔÚLCDÖмäÏÔʾͼƬ
GUI_JPEG_Draw(jpegbuffer,JPEGFile.fsize,(lcddev.width-XSize)/2-1,(lcddev.height-YSize)/2-1);
}else //·ñÔòͼƬÐèÒªËõ·Å
{
Xflag = (float)XSize*((float)member/(float)denom);
Yflag = (float)YSize*((float)member/(float)denom);
XSize = (lcddev.width-(int)Xflag)/2-1;
YSize = (lcddev.height-(int)Yflag)/2-1;
GUI_JPEG_DrawScaled(jpegbuffer,JPEGFile.fsize,XSize,YSize,member,denom);
}
break;
}
f_close(&JPEGFile); //¹Ø±ÕJPEGFileÎļþ
myfree(SRAMEX,jpegbuffer); //ÊÍ·ÅÄÚ´æ
return 0;
}
//ÔÚÖ¸¶¨Î»ÖÃÏÔʾÎÞÐè¼ÓÔص½RAMÖеÄBMPͼƬ(ÐèÎļþϵͳ֧³Ö£¡¶ÔÓÚСRAM£¬ÍƼöʹÓô˷½·¨£¡)
//JPEGFileName:ͼƬÔÚSD¿¨»òÕßÆäËû´æ´¢É豸ÖеÄ·¾¶
//mode:ÏÔʾģʽ
// 0 ÔÚÖ¸¶¨Î»ÖÃÏÔʾ£¬ÓвÎÊýx,yÈ·¶¨ÏÔʾλÖÃ
// 1 ÔÚLCDÖмäÏÔʾͼƬ£¬µ±Ñ¡Ôñ´ËģʽµÄʱºò²ÎÊýx,yÎÞЧ¡£
//x:ͼƬ×óÉϽÇÔÚLCDÖеÄxÖáλÖÃ(µ±²ÎÊýmodeΪ1ʱ£¬´Ë²ÎÊýÎÞЧ)
//y:ͼƬ×óÉϽÇÔÚLCDÖеÄyÖáλÖÃ(µ±²ÎÊýmodeΪ1ʱ£¬´Ë²ÎÊýÎÞЧ)
//member: Ëõ·Å±ÈÀýµÄ·Ö×ÓÏî
//denom:Ëõ·Å±ÈÀýµÄ·ÖĸÏî
//·µ»ØÖµ:0 ÏÔʾÕý³£,ÆäËû ʧ°Ü
int displayjpegex(u8 *JPEGFileName,u8 mode,u32 x,u32 y,int member,int denom)
{
char result;
int XSize,YSize;
float Xflag,Yflag;
GUI_JPEG_INFO JpegInfo;
result = f_open(&JPEGFile,(const TCHAR*)JPEGFileName,FA_READ); //´ò¿ªÎļþ
//Îļþ´ò¿ª´íÎó
if(result != FR_OK) return 1;
GUI_JPEG_GetInfoEx(JpegGetData,&JPEGFile,&JpegInfo);
XSize = JpegInfo.XSize; //JPEGͼƬX´óС
YSize = JpegInfo.YSize; //JPEGͼƬY´óС
switch(mode)
{
case 0: //ÔÚÖ¸¶¨Î»ÖÃÏÔʾͼƬ
if((member == 1) && (denom == 1)) //ÎÞÐèËõ·Å£¬Ö±½Ó»æÖÆ
{
GUI_JPEG_DrawEx(JpegGetData,&JPEGFile,x,y);//ÔÚÖ¸¶¨Î»ÖÃÏÔʾBMPͼƬ
}else //·ñÔòͼƬÐèÒªËõ·Å
{
GUI_JPEG_DrawScaledEx(JpegGetData,&JPEGFile,x,y,member,denom);
}
break;
case 1: //ÔÚLCDÖмäÏÔʾͼƬ
if((member == 1) && (denom == 1)) //ÎÞÐèËõ·Å£¬Ö±½Ó»æÖÆ
{
//ÔÚLCDÖмäÏÔʾͼƬ
GUI_JPEG_DrawEx(JpegGetData,&JPEGFile,(lcddev.width-XSize)/2-1,(lcddev.height-YSize)/2-1);
}else //·ñÔòͼƬÐèÒªËõ·Å
{
Xflag = (float)XSize*((float)member/(float)denom);
Yflag = (float)YSize*((float)member/(float)denom);
XSize = (lcddev.width-(int)Xflag)/2-1;
YSize = (lcddev.height-(int)Yflag)/2-1;
GUI_JPEG_DrawScaledEx(JpegGetData,&JPEGFile,XSize,YSize,member,denom);
}
break;
}
f_close(&JPEGFile); //¹Ø±ÕBMPFileÎļþ
return 0;
}
void jpegdisplay_demo(void)
{
GUI_SetBkColor(GUI_BLUE);
GUI_SetColor(GUI_RED);
GUI_SetFont(&GUI_FontHZ16);
GUI_Clear();
while(1)
{
displyjpeg("0:/PICTURE/JPEG/ʵÀýͼƬ.jpg",0,0,0, 1,1);
}
}
JpegGetData() 从外部存储器获取 JPEG 文件数据
displyjpeg ()
将 JPEG 图片加载到 RAM 中,并显示到 LCD 上,显示速度快,但是需要
大量的 RAM。
displyjpegex() 不需要将 JPEG 加载到 RAM 中,显示速度慢,但是不需要大量的 RAM。
jpegdisplay_demo () 本章实验的演示函数,在 LCD 上显示图片。
関数JpegGetData()は、外部メモリからJPEG画像データを取得するために使用され、関数displayjpegex()がJPEG画像を表示するときにパラメータとしてGUI_JPEG_GetInfoEx()に渡されます。
関数displyjpeg()は、JPEG画像を表示するために使用されます。この関数は、最初にJPEG画像のすべてのデータをRAMにロードし、次にEMWINの対応する関数を呼び出して、RAMにロードされたJPEG画像をLCDに表示します
。 RAMに入れるので、大量のRAMが必要ですが、表示は高速です。この機能は、表示するJPEG画像の位置と倍率を設定できます。
関数displayjpegex()もJPEG画像を表示します。関数displyjpeg()とは異なり、displayjpegex()はJPEG画像をRAMにロードする必要がなく、外部メモリからJPEG画像を直接読み取って表示できます。この方法ではRAMが必要です。小さいですが、displyjpeg()よりも速度が遅くなります。この関数は、表示するJPEG画像の位置と倍率を設定することもできます。
各関数がどのように機能するかを理解するために、ルーチンは私によって変更されました。
これは時間厳守の原子の現象です。見れば理解できます。