打印
[STM32F0]

ILI9325解码jpeg图片不正常!

[复制链接]
2825|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zongyu123|  楼主 | 2014-12-16 11:01 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
如题,图片解码不正常,用的是ili9325,320*240的的屏。显示英文数字正常。
​望大神们不吝赐教,谢谢。
​解码用的是ChaN的Tiny解码函数。解析出来如下图:

​代码如下:
​#include "stm32f0xx.h"#include "takepic.h"
#include "tjpgd.h"

static FRESULT res;                         // FatFs function common result code
BYTE Buff[4096] __attribute__ ((aligned(4)));
/* Dot screen size */
#define DISP_XS        320
#define DISP_YS        240
/*-----------------------------------*/
/* JPEG file loader                  */

#define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0)
//#define f_error(fp) (((fp)->flag & FA__ERROR) ? 1 : 0)
#define f_tell(fp) ((fp)->fptr)
#define f_size(fp) ((fp)->fsize)

/* User defined call-back function to input JPEG data */
static
UINT tjd_input (
        JDEC* jd,                /* Decoder object */
        BYTE* buff,                /* Pointer to the read buffer (NULL:skip) */
        UINT nd                        /* Number of bytes to read/skip from input stream */
)
{
        UINT rb;
        FIL *fil = (FIL*)jd->device;        /* Input stream of this session */

        if (buff) {        /* Read nd bytes from the input strem */
                f_read(fil, buff, nd, &rb);
                return rb;        /* Returns number of bytes could be read */

        } else {        /* Skip nd bytes on the input stream */
                return (f_lseek(fil, f_tell(fil) + nd) == FR_OK) ? nd : 0;
        }
}
static int MaskT, MaskL, MaskR, MaskB;        /* Active drawing area */

void disp_mask (
        int left,                /* Left end of active window (0 to DISP_XS-1) */
        int right,                /* Right end of active window (0 to DISP_XS-1, >=left) */
        int top,                /* Top end of active window (0 to DISP_YS-1) */
        int bottom                /* Bottom end of active window (0 to DISP_YS-1, >=top) */
)
{
        //if (left >= 0 && right < DISP_XS && left <= right && top >= 0 && bottom < DISP_XS && top <= bottom)
        {
                MaskL = left;
                MaskR = right;
                MaskT = top;
                MaskB = bottom;
        }
}

//LCDµ×²ãÏÔʾº¯Êý
void disp_blt (
        int left,                /* Left end (-32768 to 32767) */
        int right,                /* Right end (-32768 to 32767, >=left) */
        int top,                /* Top end (-32768 to 32767) */
        int bottom,                /* Bottom end (-32768 to 32767, >=right) */
        const uint16_t *pat        /* Pattern data */
)
{
        int yc, xc, xl, xs;
        uint16_t pd;

        if (left > right || top > bottom) return;         /* Check varidity */
        if (left > MaskR || right < MaskL  || top > MaskB || bottom < MaskT) return;        /* Check if in active area */

        yc = bottom - top + 1;                        /* Vertical size */
        xc = right - left + 1; xs = 0;        /* Horizontal size and skip */

        if (top < MaskT) {                /* Clip top of source image if it is out of active area */
                pat += xc * (MaskT - top);
                yc -= MaskT - top;
                top = MaskT;
        }
        if (bottom > MaskB) {        /* Clip bottom of source image if it is out of active area */
                yc -= bottom - MaskB;
                bottom = MaskB;
        }
        if (left < MaskL) {                /* Clip left of source image if it is out of active area */
                pat += MaskL - left;
                xc -= MaskL - left;
                xs += MaskL - left;
                left = MaskL;
        }
        if (right > MaskR) {        /* Clip right of source image it is out of active area */
                xc -= right - MaskR;
                xs += right - MaskR;
                right = MaskR;
        }       
        LCD_Set_Window(left, top, right, bottom);       
        LCD_WriteGRAM_EN();
        do {        /* Send image data */
                xl = xc;
                do {
                        pd = *pat++;
                        LCD_WR_DATA(pd);//ÏÔʾÏñËØ
                } while (--xl);
                pat += xs;
        } while (--yc);
        LCD_CS(1);
}
/* User defined call-back function to output RGB bitmap */
static
UINT tjd_output (
        JDEC* jd,                /* Decoder object */
        void* bitmap,        /* Bitmap data to be output */
        JRECT* rect                /* Rectangular region to output */
)
{
        jd = jd;        /* Suppress warning (device identifier is not needed) */

        /* Check user interrupt at left end */
        //if (!rect->left && __kbhit()) return 0;        /* Abort decompression */
        //if (rect->left) return 0;        /* Abort decompression */
        /* Put the rectangular into the display */
        disp_blt(rect->left, rect->right, rect->top, rect->bottom, (uint16_t*)bitmap);
        return 1;        /* Continue decompression */
}


void load_jpg (
        FIL *fp,                /* Pointer to the open file object to load */
        void *work,                /* Pointer to the working buffer (must be 4-byte aligned) */
        UINT sz_work        /* Size of the working buffer (must be power of 2) */
)
{
        JDEC jd;                /* Decoder object (124 bytes) */
        JRESULT rc;
        BYTE scale;

        //ÇåÆÁ×¢Ê͵ô
        //disp_fill(0, DISP_XS, 0, DISP_YS, 0);        /* Clear screen */
        //disp_font_color(C_WHITE);
       
        /* Prepare to decompress the file */
        rc = jd_prepare(&jd, tjd_input, work, sz_work, fp);
        if (rc == JDR_OK)
        {
                //UPrintf("sz_work:%d,&work:%d,work:%d,jd:%d\n",sz_work,&work,work,jd);
                /* Determine scale factor */
                for (scale = 0; scale < 3; scale++)
                {
                        if (((jd.width >> scale) <= DISP_XS) && ((jd.height >> scale) <= DISP_YS)) break;
                }
                /* Display size information at bottom of screen */
                //disp_locate(0, TS_HEIGHT - 1);
                //(disp_putc, "%ux%u 1/%u", jd.width, jd.height, 1 << scale);

                /* Start to decompress the JPEG file */
                rc = jd_decomp(&jd, tjd_output, scale);        /* Start to decompress */
        } else {
                /* Display error code */
                //disp_locate(0, 0);
        }
        //__getch();                //×¢ÊÍ
}
void load_file (
        const char *fn,                /* Pointer to the file name */
        void *work,                        /* Pointer to filer work area (must be word aligned) */
        UINT sz_work                /* Size of the filer work area */
)
{
        FIL fil;                        /* Pointer to a file object */
        if (f_open(&fil, fn, FA_READ) == FR_OK)
        {
//                if (strstr_ext(fn, ".BMP"))
//                {        /* BMP image viewer (24bpp, 1280pix in width max) */
//                        load_bmp(&fil, work, sz_work);
//                }
       
                load_jpg(&fil, work, sz_work);
               
//                if (strstr_ext(fn, ".IMG"))
//                {        /* Motion image viewer */
//                        load_img(&fil, work, sz_work);
//                }
//                if (strstr_ext(fn, ".WAV"))
//                {        /* Sound file player (RIFF-WAVE only) */
//                        load_wav(&fil, fn, work, sz_work);
//                }
                f_close(&fil);
        }
}

////////////////////////////////////////////////////////////////////////////////////////////////
int main(void)
{
        u16 i = 0;
        u16 j = 0;
        u16 temp = 0;
        u16 data = 0;
       
        u8 key_down = 0;
        u16 key_cnt = 0;
       
        system_init();

        disp_mask(0, DISP_XS - 1, 0, DISP_YS - 1);                //ÉèÖûæͼÇøÓò
        load_file("0:33.jpg", Buff, sizeof(Buff));        //´ò¿ªjpgÎļþ²¢½âÂëÏÔʾ
        while(1)
        {
               
        }
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

/**
  * @}
  */

/**
  * @}
  */

/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

沙发
zongyu123|  楼主 | 2014-12-16 11:05 | 只看该作者
没有大神吗?自己先顶一下~~用的是STM32F072的cpu

使用特权

评论回复
板凳
mmuuss586| | 2014-12-16 12:12 | 只看该作者

这块不熟悉,支持下;

使用特权

评论回复
地板
zongyu123|  楼主 | 2014-12-16 14:11 | 只看该作者
mmuuss586 发表于 2014-12-16 12:12
这块不熟悉,支持下;

还是要谢谢你,虽然我还没解决。

使用特权

评论回复
5
airwill| | 2014-12-16 18:02 | 只看该作者
看这情形, 像素数据应该是解码出来了, 很可能是图片边界超出屏宽度引起的. 或者长宽信息弄错了.

使用特权

评论回复
6
Eric2013| | 2014-12-16 18:45 | 只看该作者
用这个解码不如用emWin里面的,使用很方便,图形可以任意放缩,使用ChaN提供的解码好处就是不怎么耗内存,但是显示速度很慢。

使用特权

评论回复
7
zongyu123|  楼主 | 2014-12-16 19:23 | 只看该作者
Eric2013 发表于 2014-12-16 18:45
用这个解码不如用emWin里面的,使用很方便,图形可以任意放缩,使用ChaN提供的解码好处就是不怎么耗内存, ...

是的。就是因为公司选的CPU内存太低,就16K,还有文件系统什么的,所以才使用ChaN的代码。现在测试了,直接显示图片没问题,但是解码过后就有问题了,就是上传的那样子。请问大神,这可能是有哪些东西引起的呢?

使用特权

评论回复
8
zongyu123|  楼主 | 2014-12-16 19:26 | 只看该作者
airwill 发表于 2014-12-16 18:02
看这情形, 像素数据应该是解码出来了, 很可能是图片边界超出屏宽度引起的. 或者长宽信息弄错了. ...

长度信息什么的,我都打印出来了。和实际的大小是一样子的。这个解码出来是对的,主要的问题还是不知道出在哪。我猜应该是贴到LCD的时候出错了,但是又不知道该怎么改。

使用特权

评论回复
9
zongyu123|  楼主 | 2014-12-16 19:27 | 只看该作者
zongyu123 发表于 2014-12-16 19:23
是的。就是因为公司选的CPU内存太低,就16K,还有文件系统什么的,所以才使用ChaN的代码。现在测试了,直 ...

这个emWin大概要占多少内存呢?可以的话,没办法就必须换这个了。但是对于自己学习来说,还是都搞搞比较好。

使用特权

评论回复
10
Eric2013| | 2014-12-16 19:35 | 只看该作者
zongyu123 发表于 2014-12-16 19:27
这个emWin大概要占多少内存呢?可以的话,没办法就必须换这个了。但是对于自己学习来说,还是都搞搞比较 ...

你用的这个内存太小。用emWin做JPEG解码不合适。你看下你的代码这个地方是不是有问题:

LCD_Set_Window(left, top, right, bottom);        
        LCD_WriteGRAM_EN();
        do {        /* Send image data */
                xl = xc;
                do {
                        pd = *pat++;
                        LCD_WR_DATA(pd);//ÏÔʾÏñËØ
                } while (--xl);
                pat += xs;
        } while (--yc);

使用特权

评论回复
11
zongyu123|  楼主 | 2014-12-16 22:17 | 只看该作者
Eric2013 发表于 2014-12-16 19:35
你用的这个内存太小。用emWin做JPEG解码不合适。你看下你的代码这个地方是不是有问题:

LCD_Set_Window ...

好的,谢谢。
调试的时候,把那句LCD_Set_window屏蔽掉,就会一行一行的贴出来,但是每一行都只是贴同样的一块。
下一行,又是第二行的第一块。直到结束~~
别的,都是ChaN的源码了。。。

使用特权

评论回复
12
Eric2013| | 2014-12-17 10:16 | 只看该作者
zongyu123 发表于 2014-12-16 22:17
好的,谢谢。
调试的时候,把那句LCD_Set_window屏蔽掉,就会一行一行的贴出来,但是每一行都只是贴同样 ...

现在怎么样,问题解决了没有。

使用特权

评论回复
评分
参与人数 1威望 +2 收起 理由
zongyu123 + 2 已经解决了,换了个算法,谢谢你。.
13
zongyu123|  楼主 | 2014-12-17 10:17 | 只看该作者
Eric2013 发表于 2014-12-17 10:16
现在怎么样,问题解决了没有。

是LCD_Set_window这个函数的问题,还在搞。谢谢大神。

使用特权

评论回复
14
zongyu123|  楼主 | 2014-12-17 11:10 | 只看该作者
Eric2013 发表于 2014-12-17 10:16
现在怎么样,问题解决了没有。

串口打印,每一块的大小都是正确的,那应该就是贴到屏幕的方法出问题了。就是你给贴出来的那一块,但是不知道怎么修改啊

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

34

帖子

0

粉丝