RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于STM32設(shè)計(jì)的數(shù)碼相冊(cè)

DS小龍哥-嵌入式技術(shù) ? 來(lái)源:DS小龍哥-嵌入式技術(shù) ? 作者:DS小龍哥-嵌入式技 ? 2023-06-24 21:14 ? 次閱讀

一、項(xiàng)目介紹

項(xiàng)目是基于STM32設(shè)計(jì)的數(shù)碼相冊(cè),能夠通過(guò)LCD顯示屏解碼顯示主流的圖片,支持bmp、jpg、gif等格式。用戶(hù)可以通過(guò)按鍵或者觸摸屏來(lái)切換圖片,同時(shí)還可以旋轉(zhuǎn)顯示,并能夠自適應(yīng)居中顯示,小尺寸圖片居中顯示,大尺寸圖片自動(dòng)縮小顯示(超出屏幕范圍)。圖片從SD卡中獲取。

image-20230618135436038

二、設(shè)計(jì)思路

2.1 硬件設(shè)計(jì)

本項(xiàng)目所需的主要硬件:

  • STM32F103ZET6
  • LCD屏幕
  • SD卡模塊
  • 按鍵和觸摸屏

2.2 軟件設(shè)計(jì)

(1)解碼圖片

在STM32芯片中,解碼圖片需要將讀取到的數(shù)據(jù)存入圖形緩沖區(qū)中,以便進(jìn)行圖畫(huà)顯示。常用的解碼算法有JPEG解碼和BMP解碼。

(2)圖片顯示

為了更好的實(shí)現(xiàn)圖片旋轉(zhuǎn)和縮放功能,在顯示圖片時(shí)需對(duì)其進(jìn)行矩陣運(yùn)算。通過(guò)左右翻轉(zhuǎn)和上下翻轉(zhuǎn),可實(shí)現(xiàn)圖片的旋轉(zhuǎn)功能。通過(guò)計(jì)算圖片與顯示屏幕之間的比例關(guān)系并進(jìn)行縮放,實(shí)現(xiàn)自適應(yīng)居中和圖片的縮放功能。

(3)SD卡

SD卡模塊可通過(guò)SPI接口與STM32芯片進(jìn)行通信,讀取SD卡中的圖片數(shù)據(jù),實(shí)現(xiàn)對(duì)圖片的加載和顯示。

(4)按鍵和觸摸屏

在使用過(guò)程中,用戶(hù)可以通過(guò)按鍵和觸摸屏對(duì)圖片進(jìn)行切換、旋轉(zhuǎn)和縮放等操作。通過(guò)設(shè)置中斷處理函數(shù),響應(yīng)用戶(hù)的操作并及時(shí)更新顯示屏幕上的圖片。

2.3 圖片播放流程圖

image-20230618135212377

2.4 顯示效果

image-20230618135401101

image-20230618135409530

image-20230618135417655

image-20230618135426430

image-20230618135436038

三、代碼設(shè)計(jì)

3.1 主函數(shù)

#include "stm32f10x.h"
 #include "led.h"
 #include "delay.h"
 #include "key.h"
 #include "usart.h"
 #include < string.h >
 #include < stdio.h >
 #include "sd.h" //SD卡
 #include "ff.h" //文件系統(tǒng)
 #include "bmp.h" //文件系統(tǒng)
 #include "iic.h"
 #include "at24c02.h"
 #include "xpt2046.h"
 #include "lcd.h"
 ?
 ?
 FATFS fs;  // 用戶(hù)定義的文件系統(tǒng)結(jié)構(gòu)體
 int main()
 {
     DIR  dir_dp;
     FILINFO file_info;
     u32 sd_size;    //存放SD卡返回的容量
     BeepInit();       //蜂鳴器初始化
     LedInit();      //LED燈初始化 
     UsartInit(USART1,72,115200);
     KeyInit();     //按鍵初始化
     IICInit();
     LcdInit();
     TOUCH_Init(); 
     //TOUCH_ADJUST(); //觸摸屏校準(zhǔn)
     
     printf("串口工作正常!\\r\\n");
     if(SDCardDeviceInit()) 
     {
        printf("SD卡初始化失敗!\\r\\n");
     }
     
     sd_size=GetSDCardSectorCount(); //檢測(cè)SD卡大小,返回值右移11位得到以M為單位的容量
     printf("SD卡Sizeof:%d\\r\\n",sd_size >>11);
     
   f_mount(&fs,"0:",1);  // 注冊(cè)文件系統(tǒng)工作區(qū),驅(qū)動(dòng)器號(hào) 0,初始化后其他函數(shù)可使用里面的參數(shù)
     LcdClear(0xFFFF);
     
     //f_mkdir("0:/目錄創(chuàng)建測(cè)試!"); //測(cè)試OK
     //f_unlink("0:/123"); //刪除目錄,注意只能刪除空目錄
     //f_unlink("0:/1.bmp");//刪除文件
     //printf("%d\\r\\n",Show_BMP("1.bmp"));
     
     if(f_opendir(&dir_dp,"0:/bmp")!=FR_OK)printf("目錄打開(kāi)失敗!\\r\\n");
     
     //循環(huán)讀取目錄
     while(f_readdir(&dir_dp,&file_info)==FR_OK)
     {
             if(file_info.fname[0]==0)break;    //判斷目錄跳出條件,表示目錄已經(jīng)讀取完畢
             if(strstr(file_info.fname,".bmp")) //過(guò)濾目錄
             {
                     printf("文件名稱(chēng): %s,文件大小: %ld 字節(jié)\\r\\n",file_info.fname,file_info.fsize);
             }else   printf("文件名稱(chēng): %s,文件大小: %ld 字節(jié)\\r\\n",file_info.fname,file_info.fsize);
     }
     if(f_closedir(&dir_dp)!=FR_OK)printf("目錄關(guān)閉失敗!\\r\\n");
     while(1)
     {   
          LED1=!LED1;
          DelayMs(100);
     }
 }
 ?

3.2 BMP圖片解碼

#include "bmp.h"
 unsigned short RGB888ToRGB565(unsigned int n888Color)  
 {  
     unsigned short n565Color = 0;  
   
     // 獲取RGB單色,并截取高位  
     unsigned char cRed   = (n888Color & RGB888_RED)   > > 19;  
     unsigned char cGreen = (n888Color & RGB888_GREEN) > > 10;  
     unsigned char cBlue  = (n888Color & RGB888_BLUE)  > > 3;  
   
     // 連接  
     n565Color = (cRed < < 11) + (cGreen < < 5) + (cBlue < < 0);  
     return n565Color;  
 }  
 ?
 unsigned int RGB565ToRGB888(unsigned short n565Color)  
 {  
     unsigned int n888Color = 0;  
   
     // 獲取RGB單色,并填充低位  
     unsigned char cRed   = (n565Color & RGB565_RED)    > > 8;  
     unsigned char cGreen = (n565Color & RGB565_GREEN)  > > 3;  
     unsigned char cBlue  = (n565Color & RGB565_BLUE)   < < 3;  
   
     // 連接  
     n888Color = (cRed < < 16) + (cGreen < < 8) + (cBlue < < 0);  
     return n888Color;  
 }  
 ?
 ?
 ?
 /*
 函數(shù)功能:實(shí)現(xiàn)截圖功能
 參    數(shù):
                 char filename:文件名稱(chēng)
 返 回 值:0表示成功,1表示失敗
 */
 u8 C_BMP(const char *filename,u32 Width,u32 Height)
 {
     FIL  file; // 用戶(hù)定義的文件系統(tǒng)結(jié)構(gòu)體
     u8   res;  // 保存文件操作的返回值
     BITMAPFILEHEADER BmpHead; //保存圖片文件頭的信息
   BITMAPINFOHEADER BmpInfo; //圖片參數(shù)信息
     char *p;
     u32 cnt,c_32;
     int x,y;
     u16 c_16; //存放16位的顏色
     
     /*1. 創(chuàng)建一張BMP圖片*/
     res = f_open(&file,filename, FA_OPEN_ALWAYS | FA_WRITE);
     if(res!=0)return 1;
     
     /*2. 創(chuàng)建BMP的圖片頭參數(shù)*/
     memset(&BmpHead,0,sizeof(BITMAPFILEHEADER)); //將指定空間賦值為指定的值
     p=(char*)&BmpHead.bfType; //填充BMP圖片的類(lèi)型
     *p='B';
     *(p+1)='M';
 ?
     //BmpHead.bfType=0x4d42;//'B''M'   //0x4d42
     BmpHead.bfSize=Width*Height*3+54;  //圖片的總大小
     BmpHead.bfOffBits=54;              //圖片數(shù)據(jù)的偏移量
   res =f_write(&file,&BmpHead,sizeof(BITMAPFILEHEADER),&cnt);
     if(res!=0)return 1;
     
     /*3. 創(chuàng)建BMP圖片的參數(shù)*/
     memset(&BmpInfo,0,sizeof(BITMAPINFOHEADER));
     BmpInfo.biSize=sizeof(BITMAPINFOHEADER); //當(dāng)前結(jié)構(gòu)體大小
     BmpInfo.biWidth=Width;
     BmpInfo.biHeight=Height;
     BmpInfo.biPlanes=1;
     BmpInfo.biBitCount=24;
     res =f_write(&file,&BmpInfo,sizeof(BITMAPINFOHEADER),&cnt);
     if(res!=0)return 1;
         
     /*4. 讀取LCD屏的顏色數(shù)據(jù),用于創(chuàng)建BMP圖片*/
     for(y=Height-1;y >=0;y--)
     {
           for(x=0;x< Width;x++)
           {
                 c_16=LcdReadPoint(x,y); //讀取LCD屏上一個(gè)點(diǎn)的顏色
                   c_32=RGB565ToRGB888(c_16); //顏色的轉(zhuǎn)換
                   res =f_write(&file,&c_32,3,&cnt);
                   if(res!=0)return 1;
             }
     }
     
     /*5. 關(guān)閉文件*/
     f_close(&file);
 }
 ?
 ?
 /*
 函數(shù)功能:BMP圖片顯示功能
 參    數(shù):
                 char filename:文件名稱(chēng)
 返 回 值:0表示成功,1表示失敗
 */
 u8 Show_BMP(const char *filename)
 {
     FIL  file; // 用戶(hù)定義的文件系統(tǒng)結(jié)構(gòu)體
     u8   res;  // 保存文件操作的返回值
     BITMAPFILEHEADER BmpHead; //保存圖片文件頭的信息
   BITMAPINFOHEADER BmpInfo; //圖片參數(shù)信息
     char *p;
     u32 cnt,c_24;
     int x,y;
     u16 c_16; //存放16位的顏色
     
     /*1. 打開(kāi)一張BMP圖片*/
     res = f_open(&file,filename,FA_READ);
     if(res!=0)return 1;
     
     /*2. 讀取BMP的圖片頭參數(shù)*/
   res =f_read(&file,&BmpHead,sizeof(BITMAPFILEHEADER),&cnt);
     if(res!=0)return 1;
     
     /*3. 讀取BMP圖片的參數(shù)*/
     res =f_read(&file,&BmpInfo,sizeof(BITMAPINFOHEADER),&cnt);
     if(res!=0)return 1;
     
     /*4.顯示BMP圖片*/
     f_lseek(&file,BmpHead.bfOffBits); //移動(dòng)到RGB數(shù)據(jù)的存放位置
     
     //后期的優(yōu)化:讀取一行的數(shù)據(jù),再顯示一行。
    for(y=0;y< BmpInfo.biHeight;y++)
      {
             for(x=0;x< BmpInfo.biWidth;x++)
          {
                 res =f_read(&file,&c_24,3,&cnt);
                     if(res!=0)return 1;
                 c_16=RGB888ToRGB565(c_24); //轉(zhuǎn)換顏色
                 LcdDrawPoint(x,y,c_16);
          }
      }
     /*5. 關(guān)閉文件*/
     f_close(&file);
 }
 ?
 ?

3.3 jpeg圖片解碼

#include "piclib.h"
 #include "nt35310_lcd.h"
 _pic_info picinfo;      //圖片信息
 _pic_phy pic_phy;         //圖片顯示物理接口    
 ?
 /*
 函數(shù)功能: 劃?rùn)M線函數(shù),需要自己實(shí)現(xiàn)
 */
 void Picture_DrawLine(u16 x0,u16 y0,u16 len,u16 color)
 {
     NT35310_Fill(x0,y0,x0+len-1,y0,color);  
 }
 ?
 /*
 函數(shù)功能: 矩形填充顏色
 函數(shù)參數(shù):
         x,y:起始坐標(biāo)
         width,height:寬度和高度。
         color:顏色數(shù)組
 */
 void Picture_FillColor(u16 x,u16 y,u16 width,u16 height,u16 *color)
 {  
     NT35310_DrawRectangle(x,y,x+width-1,y+height-1,*color); 
 }
 ?
 /*
 函數(shù)功能: 畫(huà)圖初始化,在畫(huà)圖之前,必須先調(diào)用此函數(shù)
 函數(shù)參數(shù): 指定畫(huà)點(diǎn)/讀點(diǎn)
 */
 void Picture_DisplayInit(void)
 {
     pic_phy.draw_point=NT35310_DrawPoint;    //畫(huà)點(diǎn)函數(shù)實(shí)現(xiàn)
     pic_phy.fill=NT35310_Fill;                       //填充函數(shù)實(shí)現(xiàn),僅GIF需要
     pic_phy.draw_hline=Picture_DrawLine;     //畫(huà)線函數(shù)實(shí)現(xiàn),僅GIF需要
     pic_phy.fillcolor=Picture_FillColor;     //顏色填充函數(shù)實(shí)現(xiàn),僅TJPGD需要 
     picinfo.lcdwidth=Lcd_Width;                          //得到LCD的寬度像素
     picinfo.lcdheight=Lcd_Height;                        //得到LCD的高度像素
 ?
     picinfo.ImgWidth=0; //初始化寬度為0
     picinfo.ImgHeight=0;//初始化高度為0
     picinfo.Div_Fac=0;  //初始化縮放系數(shù)為0
     picinfo.S_Height=0; //初始化設(shè)定的高度為0
     picinfo.S_Width=0;  //初始化設(shè)定的寬度為0
     picinfo.S_XOFF=0;     //初始化x軸的偏移量為0
     picinfo.S_YOFF=0;     //初始化y軸的偏移量為0
     picinfo.staticx=0;  //初始化當(dāng)前顯示到的x坐標(biāo)為0
     picinfo.staticy=0;  //初始化當(dāng)前顯示到的y坐標(biāo)為0
 }
 ?
 ?
 /*
 函數(shù)功能: 初始化智能畫(huà)點(diǎn)
 說(shuō)明: 內(nèi)部調(diào)用
 */
 void Picture_PointInit(void)
 {
     float temp,temp1;      
     temp=(float)picinfo.S_Width/picinfo.ImgWidth;
     temp1=(float)picinfo.S_Height/picinfo.ImgHeight;                         
     if(temp< temp1)temp1=temp;//取較小的那個(gè)    
     if(temp1 >1)temp1=1;   
     //使圖片處于所給區(qū)域的中間
     picinfo.S_XOFF+=(picinfo.S_Width-temp1*picinfo.ImgWidth)/2;
     picinfo.S_YOFF+=(picinfo.S_Height-temp1*picinfo.ImgHeight)/2;
     temp1*=8192;//擴(kuò)大8192倍    
     picinfo.Div_Fac=temp1;
     picinfo.staticx=0xffff;
     picinfo.staticy=0xffff;//放到一個(gè)不可能的值上面                                                        
 }  
 ?
 /*
 函數(shù)功能: 判斷這個(gè)像素是否可以顯示
 函數(shù)參數(shù):
             (x,y) :像素原始坐標(biāo)
             chg   :功能變量.
 返回值:0,不需要顯示.1,需要顯示
 */
 u8 Picture_is_Pixel(u16 x,u16 y,u8 chg)
 {                 
     if(x!=picinfo.staticx||y!=picinfo.staticy)
     {
         if(chg==1)
         {
             picinfo.staticx=x;
             picinfo.staticy=y;
         } 
         return 1;
     }else return 0;
 }
 ?
 extern u8 jpg_decode(const u8 *filename);
 ?
 /*
 函數(shù)功能: 繪制圖片
 函數(shù)參數(shù):
                 FileName:要顯示的圖片文件  BMP/JPG/JPEG/GIF
                 x,y,width,height:坐標(biāo)及顯示區(qū)域尺寸
                 fast:使能jpeg/jpg小圖片(圖片尺寸小于等于液晶分辨率)快速解碼,0,不使能;1,使能.
                 函數(shù)說(shuō)明: 圖片在開(kāi)始和結(jié)束的坐標(biāo)點(diǎn)范圍內(nèi)顯示
 */
 u8 Picture_DisplayJPG(const u8 *filename,u16 x,u16 y,u16 width,u16 height,u8 fast)
 {   
     u8  res;//返回值
     
     //顯示的圖片高度、寬度
     picinfo.S_Height=height;
     picinfo.S_Width=width;
 ?
     //顯示的開(kāi)始坐標(biāo)點(diǎn)
     picinfo.S_YOFF=y;
     picinfo.S_XOFF=x;
     
     //解碼JPG/JPEG         
   res=jpg_decode(filename);             //解碼JPG/JPEG                                                   
     return res;
 }
 ?

3.4 gif圖片解碼

#include "piclib.h"
 #include < stm32f10x.h >
 #include "gif.h"     
 #include "ff.h" 
 #include "delay.h"      
 #include < string.h >
 ?
 const u16 _aMaskTbl[16] =
 {
     0x0000, 0x0001, 0x0003, 0x0007,
     0x000f, 0x001f, 0x003f, 0x007f,
     0x00ff, 0x01ff, 0x03ff, 0x07ff,
     0x0fff, 0x1fff, 0x3fff, 0x7fff,
 };    
 const u8 _aInterlaceOffset[]={8,8,4,2};
 const u8 _aInterlaceYPos  []={0,4,2,1};
  
 u8 gifdecoding=0;//標(biāo)記GIF正在解碼.
 ?
 //檢測(cè)GIF頭
 //返回值:0,是GIF89a/87a;非零,非GIF89a/87a
 u8 gif_check_head(FIL *file)
 {
     u8 gifversion[6];
     u32 readed;
     u8 res;
     res=f_read(file,gifversion,6,(UINT*)&readed);
     if(res)return 1;       
     if((gifversion[0]!='G')||(gifversion[1]!='I')||(gifversion[2]!='F')||
     (gifversion[3]!='8')||((gifversion[4]!='7')&&(gifversion[4]!='9'))||
     (gifversion[5]!='a'))return 2;
     else return 0;  
 }
 ?
 //將RGB888轉(zhuǎn)為RGB565
 //ctb:RGB888顏色數(shù)組首地址.
 //返回值:RGB565顏色.
 u16 gif_getrgb565(u8 *ctb) 
 {
     u16 r,g,b;
     r=(ctb[0] >>3)&0X1F;
     g=(ctb[1] >>2)&0X3F;
     b=(ctb[2] >>3)&0X1F;
     return b+(g< 5)+(r< 11);
 }
 ?
 //讀取顏色表
 //file:文件;
 //gif:gif信息;
 //num:tbl大小.
 //返回值:0,OK;其他,失敗;
 u8 gif_readcolortbl(FIL *file,gif89a * gif,u16 num)
 {
     u8 rgb[3];
     u16 t;
     u8 res;
     u32 readed;
     for(t=0;t< num;t++)
     {
         res=f_read(file,rgb,3,(UINT*)&readed);
         if(res)return 1;//讀錯(cuò)誤
         gif- >colortbl[t]=gif_getrgb565(rgb);
     }
     return 0;
 } 
 //得到邏輯屏幕描述,圖像尺寸等
 //file:文件;
 //gif:gif信息;
 //返回值:0,OK;其他,失敗;
 u8 gif_getinfo(FIL *file,gif89a * gif)
 {
     u32 readed;  
     u8 res;   
     res=f_read(file,(u8*)&gif- >gifLSD,7,(UINT*)&readed);
     if(res)return 1;
     if(gif- >gifLSD.flag&0x80)//存在全局顏色表
     {
         gif- >numcolors=2< gifLSD.flag&0x07);//得到顏色表大小
         if(gif_readcolortbl(file,gif,gif- >numcolors))return 1;//讀錯(cuò)誤 
     }      
     return 0;
 }
 //保存全局顏色表    
 //gif:gif信息;
 void gif_savegctbl(gif89a* gif)
 {
     u16 i=0;
     for(i=0;i< 256;i++)gif- >bkpcolortbl[i]=gif- >colortbl[i];//保存全局顏色.
 }
 //恢復(fù)全局顏色表    
 //gif:gif信息;
 void gif_recovergctbl(gif89a* gif)
 {
     u16 i=0;
     for(i=0;i< 256;i++)gif- >colortbl[i]=gif- >bkpcolortbl[i];//恢復(fù)全局顏色.
 }
 ?
 //初始化LZW相關(guān)參數(shù)       
 //gif:gif信息;
 //codesize:lzw碼長(zhǎng)度
 void gif_initlzw(gif89a* gif,u8 codesize) 
 {
     memset((u8 *)gif- >lzw, 0, sizeof(LZW_INFO));
     gif- >lzw- >SetCodeSize  = codesize;
     gif- >lzw- >CodeSize     = codesize + 1;
     gif- >lzw- >ClearCode    = (1 < < codesize);
     gif- >lzw- >EndCode      = (1 < < codesize) + 1;
     gif- >lzw- >MaxCode      = (1 < < codesize) + 2;
     gif- >lzw- >MaxCodeSize  = (1 < < codesize) < < 1;
     gif- >lzw- >ReturnClear  = 1;
     gif- >lzw- >LastByte     = 2;
     gif- >lzw- >sp           = gif- >lzw- >aDecompBuffer;
 }
 ?
 //讀取一個(gè)數(shù)據(jù)塊
 //gfile:gif文件;
 //buf:數(shù)據(jù)緩存區(qū)
 //maxnum:最大讀寫(xiě)數(shù)據(jù)限制
 u16 gif_getdatablock(FIL *gfile,u8 *buf,u16 maxnum) 
 {
     u8 cnt;
     u32 readed;
     u32 fpos;
     f_read(gfile,&cnt,1,(UINT*)&readed);//得到LZW長(zhǎng)度            
     if(cnt) 
     {
         if (buf)//需要讀取 
         {
             if(cnt >maxnum)
             {
                 fpos=f_tell(gfile);
                 f_lseek(gfile,fpos+cnt);//跳過(guò)
                 return cnt;//直接不讀
             }
             f_read(gfile,buf,cnt,(UINT*)&readed);//得到LZW長(zhǎng)度  
         }else   //直接跳過(guò)
         {
             fpos=f_tell(gfile);
             f_lseek(gfile,fpos+cnt);//跳過(guò)
         }
     }
     return cnt;
 }
 ?
 //ReadExtension      
 //Purpose:
 //Reads an extension block. One extension block can consist of several data blocks.
 //If an unknown extension block occures, the routine failes.
 //返回值:0,成功;
 //       其他,失敗
 u8 gif_readextension(FIL *gfile,gif89a* gif, int *pTransIndex,u8 *pDisposal)
 {
     u8 temp;
     u32 readed;  
     u8 buf[4];  
     f_read(gfile,&temp,1,(UINT*)&readed);//得到長(zhǎng)度      
     switch(temp)
     {
         case GIF_PLAINTEXT:
         case GIF_APPLICATION:
         case GIF_COMMENT:
             while(gif_getdatablock(gfile,0,256) >0);         //獲取數(shù)據(jù)塊
             return 0;
         case GIF_GRAPHICCTL://圖形控制擴(kuò)展塊
             if(gif_getdatablock(gfile,buf,4)!=4)return 1;   //圖形控制擴(kuò)展塊的長(zhǎng)度必須為4 
             gif- >delay=(buf[2]< 8)|buf[1];                  //得到延時(shí) 
             *pDisposal=(buf[0] >>2)&0x7;                     //得到處理方法
             if((buf[0]&0x1)!=0)*pTransIndex=buf[3];         //透明色表 
             f_read(gfile,&temp,1,(UINT*)&readed);           //得到LZW長(zhǎng)度   
             if(temp!=0)return 1;                            //讀取數(shù)據(jù)塊結(jié)束符錯(cuò)誤.
             return 0;
     }
     return 1;//錯(cuò)誤的數(shù)據(jù)
 }
 ?
 //從LZW緩存中得到下一個(gè)LZW碼,每個(gè)碼包含12位
 //返回值:< 0,錯(cuò)誤.
 //       其他,正常.
 int gif_getnextcode(FIL *gfile,gif89a* gif) 
 {
     int i,j,End;
     long Result;
     if(gif- >lzw- >ReturnClear)
     {
         //The first code should be a clearcode.
         gif- >lzw- >ReturnClear=0;
         return gif- >lzw- >ClearCode;
     }
     End=gif- >lzw- >CurBit+gif- >lzw- >CodeSize;
     if(End >=gif- >lzw- >LastBit)
     {
         int Count;
         if(gif- >lzw- >GetDone)return-1;//Error 
         gif- >lzw- >aBuffer[0]=gif- >lzw- >aBuffer[gif- >lzw- >LastByte-2];
         gif- >lzw- >aBuffer[1]=gif- >lzw- >aBuffer[gif- >lzw- >LastByte-1];
         if((Count=gif_getdatablock(gfile,&gif- >lzw- >aBuffer[2],300))==0)gif- >lzw- >GetDone=1;
         if(Count< 0)return -1;//Error 
         gif- >lzw- >LastByte=2+Count;
         gif- >lzw- >CurBit=(gif- >lzw- >CurBit-gif- >lzw- >LastBit)+16;
         gif- >lzw- >LastBit=(2+Count)*8;
         End=gif- >lzw- >CurBit+gif- >lzw- >CodeSize;
     }
     j=End >>3;
     i=gif- >lzw- >CurBit >>3;
     if(i==j)Result=(long)gif- >lzw- >aBuffer[i];
     else if(i+1==j)Result=(long)gif- >lzw- >aBuffer[i]|((long)gif- >lzw- >aBuffer[i+1]< 8);
     else Result=(long)gif- >lzw- >aBuffer[i]|((long)gif- >lzw- >aBuffer[i+1]< 8)|((long)gif- >lzw- >aBuffer[i+2]< 16);
     Result=(Result >>(gif- >lzw- >CurBit&0x7))&_aMaskTbl[gif- >lzw- >CodeSize];
     gif- >lzw- >CurBit+=gif- >lzw- >CodeSize;
     return(int)Result;
 }
 ?
 ?
 //得到LZW的下一個(gè)碼
 //返回值:< 0,錯(cuò)誤(-1,不成功;-2,讀到結(jié)束符了)
 //       >=0,OK.(LZW的第一個(gè)碼)
 int gif_getnextbyte(FIL *gfile,gif89a* gif) 
 {
     int i,Code,Incode;
     while((Code=gif_getnextcode(gfile,gif)) >=0)
     {
         if(Code==gif- >lzw- >ClearCode)
         {
             //Corrupt GIFs can make this happen  
             if(gif- >lzw- >ClearCode >=(1<
聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • lcd
    lcd
    +關(guān)注

    關(guān)注

    34

    文章

    4424

    瀏覽量

    167395
  • STM32
    +關(guān)注

    關(guān)注

    2270

    文章

    10895

    瀏覽量

    355721
  • 編解碼
    +關(guān)注

    關(guān)注

    1

    文章

    140

    瀏覽量

    19612
  • STM32F103ZET6
    +關(guān)注

    關(guān)注

    9

    文章

    67

    瀏覽量

    21121
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    STM32應(yīng)用案例 基于STM32F103ZE開(kāi)發(fā)的數(shù)碼相冊(cè)

    1.硬件平臺(tái) CPU:STM32F103ZE 屏幕:3.5寸TFTLCD屏 觸控:電阻式觸摸屏xpt2046 SD卡、外擴(kuò)Sram
    的頭像 發(fā)表于 06-02 09:09 ?7313次閱讀
    <b class='flag-5'>STM32</b>應(yīng)用案例 基于<b class='flag-5'>STM32</b>F103ZE開(kāi)發(fā)的<b class='flag-5'>數(shù)碼相冊(cè)</b>

    Linux驅(qū)動(dòng)開(kāi)發(fā)_數(shù)碼相冊(cè)項(xiàng)目、360WIFI驅(qū)動(dòng)移植介紹

    這篇文章介紹兩個(gè)知識(shí)點(diǎn): 數(shù)碼相冊(cè)要求介紹、貼出案例代碼、介紹360隨身WIFI的驅(qū)動(dòng)移植注意事項(xiàng)。
    的頭像 發(fā)表于 09-17 15:51 ?1714次閱讀
    Linux驅(qū)動(dòng)開(kāi)發(fā)_<b class='flag-5'>數(shù)碼相冊(cè)</b>項(xiàng)目、360WIFI驅(qū)動(dòng)移植介紹

    基于STM32L431低功耗芯片制作的電子墨水屏相冊(cè)

    為解決傳統(tǒng)相冊(cè)及桌面照片擺臺(tái)只能展示固定圖片這一問(wèn)題,本次設(shè)計(jì)的基于STM32L431RCT6低功耗芯片制作的電子墨水屏相冊(cè),可以顯示電子圖片
    的頭像 發(fā)表于 11-08 11:39 ?3376次閱讀
    基于<b class='flag-5'>STM32</b>L431低功耗芯片制作的電子墨水屏<b class='flag-5'>相冊(cè)</b>

    高清晰影樓相冊(cè)制作系統(tǒng) 綠色特別版

    高清晰影樓相冊(cè)制作系統(tǒng) 2008 V3.5 綠色特別版軟件語(yǔ)言: 簡(jiǎn)體中文 運(yùn)行環(huán)境: Win9X/2000/XP/2003/Vista/ 軟件簡(jiǎn)介: 高清晰影樓相冊(cè)制作系統(tǒng)是一款專(zhuān)業(yè)的影樓相冊(cè)制作
    發(fā)表于 03-02 11:44

    單片機(jī)控制的DIY數(shù)碼相冊(cè)顯示

    本帖最后由 eehome 于 2013-1-5 09:52 編輯 單片機(jī)控制的DIY數(shù)碼相冊(cè)顯示
    發(fā)表于 08-15 23:05

    【Aworks申請(qǐng)】基于ARM9的電子相冊(cè)

    申請(qǐng)理由:本人是一名嵌入式開(kāi)發(fā)從業(yè)者,對(duì)嵌入式開(kāi)發(fā)有著濃厚的興趣,本套開(kāi)發(fā)板具有極其豐富的學(xué)習(xí)資源,非常希望能夠獲得此次機(jī)會(huì),對(duì)ARM9嵌入式系統(tǒng)開(kāi)發(fā)有很大的幫助。項(xiàng)目描述:通過(guò)開(kāi)發(fā)板的學(xué)習(xí)之后,制作一個(gè)簡(jiǎn)單的可以控制的電子數(shù)碼相冊(cè),簡(jiǎn)單,美觀。為今后的工作學(xué)習(xí)打下良好的基礎(chǔ)。
    發(fā)表于 07-15 08:58

    相冊(cè)

    一幅畫(huà)面,于是您的所有喜愛(ài)的圖片都到這里了。但這也是有點(diǎn)限制的,因?yàn)榇鎯?chǔ)卡的空間畢竟是有限的,而且我們有很多圖片常常就是放在網(wǎng)上的相冊(cè)里的,如果可以把網(wǎng)上相冊(cè)里的圖片直接放到我桌上的數(shù)碼相冊(cè)上就好
    發(fā)表于 02-22 10:27

    阿甘老師DREAMER開(kāi)發(fā)板零基礎(chǔ)51單片機(jī)AVR單片機(jī)視頻教程全集

    了TFT彩屏(ILI9325驅(qū)動(dòng)),SD卡(SC+HC)的視頻教學(xué)而且還有數(shù)碼相冊(cè)的聯(lián)合實(shí)際應(yīng)用,還算是比較不錯(cuò),分享到這里有需要的朋友下載吧。
    發(fā)表于 03-23 08:19

    stm32控制4位數(shù)碼管_stm32控制共陰數(shù)碼

    本文主要介紹了stm32控制4位共陽(yáng)數(shù)碼管輸出計(jì)數(shù)程序設(shè)計(jì)和stm32控制共陰數(shù)碼管程序設(shè)計(jì)。首先我們來(lái)了解一下數(shù)碼管的原理圖。用
    發(fā)表于 01-16 17:07 ?7.6w次閱讀
    用<b class='flag-5'>stm32</b>控制4位<b class='flag-5'>數(shù)碼</b>管_<b class='flag-5'>stm32</b>控制共陰<b class='flag-5'>數(shù)碼</b>管

    小米電視5共享相冊(cè)功能上線 可通過(guò)MIUI共享相冊(cè)

    11月25日消息,小米電視部總經(jīng)理李肖爽今天宣布,小米電視5共享相冊(cè)功能已上線,沒(méi)有收到應(yīng)用更新的用戶(hù)可以在電視應(yīng)用商店里搜索相冊(cè)應(yīng)用,手動(dòng)更新,電視相冊(cè)App版本號(hào)1.1.0,手機(jī)相冊(cè)
    的頭像 發(fā)表于 11-26 08:47 ?3553次閱讀

    Linux小項(xiàng)目-數(shù)碼相冊(cè)設(shè)計(jì)

    這是基于Linux系統(tǒng)開(kāi)發(fā)板設(shè)計(jì)一個(gè)小項(xiàng)目-數(shù)碼相冊(cè),在LCD屏上可以顯示完成常見(jiàn)的圖片顯示,翻頁(yè)、旋轉(zhuǎn)、縮放等功能。
    的頭像 發(fā)表于 08-14 09:15 ?1980次閱讀

    FPGA增強(qiáng)了數(shù)碼相冊(cè)功能

    隨著我們不斷以像素為單位捕獲生活快照,我們正在積累一系列軟件工具和設(shè)備來(lái)查看,編輯,存儲(chǔ),個(gè)性化和共享我們的數(shù)碼照片。一個(gè)能夠可靠地提供所有這些功能的單一、易于使用的系統(tǒng)將簡(jiǎn)化和增強(qiáng)照片制作過(guò)程。
    的頭像 發(fā)表于 10-25 11:25 ?912次閱讀
    FPGA增強(qiáng)了<b class='flag-5'>數(shù)碼相冊(cè)</b>功能

    通過(guò)ESP32制作數(shù)碼相冊(cè)

    電子發(fā)燒友網(wǎng)站提供《通過(guò)ESP32制作數(shù)碼相冊(cè).zip》資料免費(fèi)下載
    發(fā)表于 06-16 11:30 ?2次下載
    通過(guò)ESP32制作<b class='flag-5'>數(shù)碼相冊(cè)</b>

    基于Java Web電子相冊(cè)

    基于Java web的電子相冊(cè)系統(tǒng)
    發(fā)表于 06-26 15:25 ?0次下載

    HarmonyOS開(kāi)發(fā)案例:【電子相冊(cè)

    如何實(shí)現(xiàn)一個(gè)簡(jiǎn)單的電子相冊(cè)應(yīng)用的開(kāi)發(fā)
    的頭像 發(fā)表于 05-08 09:32 ?672次閱讀
    HarmonyOS開(kāi)發(fā)案例:【電子<b class='flag-5'>相冊(cè)</b>】
    RM新时代网站-首页