请教下,使用 stm32f7x的硬件 jpeg 解码功能,图片不能够横屏显示

2019-07-20 14:06发布

本帖最后由 hpdell 于 2017-5-20 15:06 编辑

请教下,使用 stm32f7x的硬件 jpeg 解码功能,图片不能够横屏显示??

但是 显示字符,画图等完全可以横屏显示(四个方向可以任意显示),

还有在图片上显示字符,具体见下面程序的描述

jpeg 解码函数如下:

// _path 文件佳及路径
uint8_t  JPEG_Display(char  *_path)
{
  uint32_t TimeBegin, TimeEnd;
  uint32_t xPos = 0, yPos = 0;
  FRESULT  res;
  FATFS    * _jpeg_fs = 0;

  TimeBegin = HAL_GetTick();

  _jpeg_fs  = (FATFS *)mymalloc(SRAMIN, sizeof(FATFS));

  if( (!_jpeg_fs) )
    return 0xff;  

  /*##-4- Register the file system object to the FatFs module ##############*/
  res = f_mount(_jpeg_fs, (TCHAR const*)"0:", 0); // == FR_OK)  

  if(res == FR_OK )
  {
    /*##-5- Open the JPG file with read access #############################*/
    res = f_open(&JPEG_File, (TCHAR const*)_path, FA_READ);
    if(res == FR_OK )
    {
      /*##-6- JPEG decoding with IT (Not Blocking ) Method ################*/
      JPEG_Decode_IT(&JPEG_Handle, &JPEG_File, JPEG_OUTPUT_DATA_BUFFER);

      /*##-7- Wait till end of JPEG decoding and perfom Input/Output Processing in BackGround  #*/
      do
      {
        JPEG_InputHandler(&JPEG_Handle);
        JpegProcessing_End = JPEG_OutputHandler(&JPEG_Handle);

      }while(JpegProcessing_End == 0);        

      /*##-8- Get JPEG Info  ###############################################*/
      HAL_JPEG_GetInfo(&JPEG_Handle, &JPEG_Info);

      printf("JPEG_Info.ImageWidth = %d ", JPEG_Info.ImageWidth);
      printf("JPEG_Info.ImageHeight = %d ", JPEG_Info.ImageHeight);      

      /*##-9- Copy RGB decoded Data to the display FrameBuffer  ############*/

      if(( g_LcdDirection == 0) || (g_LcdDirection == 2))  // 竖屏,竖屏180
      {
        xPos = (BSP_LCD_GetXSize() - JPEG_Info.ImageWidth)  / 2;
        yPos = (BSP_LCD_GetYSize() - JPEG_Info.ImageHeight) / 2;
      }
      else  // 横屏,横屏180
      {
        xPos = (BSP_LCD_GetYSize() - JPEG_Info.ImageWidth)  / 2;
        yPos = (BSP_LCD_GetXSize() - JPEG_Info.ImageHeight) / 2;      
      }


      JPEG_DMA2D_CopyBuffer((uint32_t *)JPEG_OUTPUT_DATA_BUFFER, (uint32_t *)JPEG_LCD_FRAME_BUFFER,
                            xPos , yPos,
                            JPEG_Info.ImageWidth, JPEG_Info.ImageHeight);




      /*##-10- Close the JPG file ##########################################*/
      f_close(&JPEG_File);      
    }
    else
    {
      printf("JPEG_Display f_open Error ");
    }  
  }
  else
  {
    printf("JPEG_Display f_mount Error ");
  }

  TimeEnd = HAL_GetTick();
  printf("JPEG  Display  End   ... ... %dms " ,  TimeEnd - TimeBegin);

  // 显示文件名
  BSP_LTDC_DispStringAt(240, 1280/2-230, LCD_COLOR_BLUE,  // 显示的文本颜 {MOD}
                      LCD_COLOR_TRANSPARENT,     // 显示的背景颜 {MOD}
                      &FontAscii16x24,
                      (uint8_t *)_path);         //

  BSP_LTDC_DispStringAt(240, 1280/2-195, LCD_COLOR_BLUE,  // 显示的文本颜 {MOD}
                      LCD_COLOR_TRANSPARENT,     // 显示的背景颜 {MOD}
                      &FontAscii16x24,
                      (uint8_t *)"硬件解码JPEG显示 OK");
  return 0;
}




/**
  * @brief  Copy the Decoded image to the display Frame buffer.
  * @param  pSrc: Pointer to source buffer
  * @param  pDst: Pointer to destination buffer
  * @param  x: destination horizenatl offset.
  * @param  y: destination Vertical offset.
  * @param  xSize: image width
  * @param  ysize: image Height
  * @retval None
  */

static void JPEG_DMA2D_CopyBuffer(uint32_t *pSrc, uint32_t *pDst,
                                  uint16_t x, uint16_t y,
                                  uint16_t xsize, uint16_t ysize)
{   
  #if   1
    #define  DMA2D_Handle  hdma2d_eval
  #else
    static DMA2D_HandleTypeDef    DMA2D_Handle;
  #endif

  uint32_t source      = (uint32_t)pSrc;
  uint32_t destination = 0;

        uint16_t  OutputOffset = 0;     // 行偏移
        uint16_t  NumberOfLine = 0;     // 行数,表示我们显示的数据需要的行数
        uint16_t  PixelPerLine = 0;            // 每行像素数, 每行需要显示多少个像素点   

  uint16_t   _usX, _usY, _usWidth, _usHeight;

  _usX = x;
  _usY = y;
  _usWidth  = xsize;
  _usHeight = ysize;

  destination = (uint32_t)pDst;

  /*##-1- Configure the DMA2D Mode, Color Mode and output offset #############*/
  DMA2D_Handle.Init.Mode          = DMA2D_M2M_PFC;

  if (g_LcdDirection == 0)              // 竖屏 LCD 屏 默认的扫描方向
  {
    destination += (LTDC_PIX_SIZE * (uint32_t)(_usY * LCD_PIXEL_WIDTH + _usX));  // 竖屏 ok
    OutputOffset = LCD_PIXEL_WIDTH - _usWidth;
                NumberOfLine = _usHeight;
                PixelPerLine = _usWidth;
  }


  //注:在计算地址(XaddrPutPixel = xxx)里面使用到的 - _usHeight,- _usWidth,原因为
  //    lcd 屏的x,y 方向是可以自增的,所以需要 减去高度与宽度(意思就是反向显示)
  else if (g_LcdDirection == 2)        // 竖屏 180°
  {
    destination += (LTDC_PIX_SIZE * (uint32_t)((LCD_PIXEL_HEIGHT - _usHeight - _usY - 1) * LCD_PIXEL_WIDTH + (LCD_PIXEL_WIDTH - _usWidth - _usX - 1)));   // 180°竖屏

    OutputOffset = LCD_PIXEL_WIDTH - _usWidth;
                NumberOfLine = _usHeight ;
                PixelPerLine = _usWidth;  
  }  


  else if (g_LcdDirection == 1)        // 横屏
  {
    destination += (LTDC_PIX_SIZE * (uint32_t)( (_usX * LCD_PIXEL_WIDTH ) + (LCD_PIXEL_WIDTH - _usHeight - _usY - 1)));     // 横屏
    OutputOffset = LCD_PIXEL_WIDTH - _usHeight;
                NumberOfLine = _usWidth ;
                PixelPerLine = _usHeight ;   
  }
  else if (g_LcdDirection == 3)        // 横屏180°
  {
    destination += (LTDC_PIX_SIZE * (uint32_t)((LCD_PIXEL_HEIGHT - _usX - _usWidth - 1) * LCD_PIXEL_WIDTH  + _usY));    // 横屏180
    OutputOffset = LCD_PIXEL_WIDTH - _usHeight;
                NumberOfLine = _usWidth ;
                PixelPerLine = _usHeight ;   
  }   

  DMA2D_Handle.Init.OutputOffset  = OutputOffset;
  DMA2D_Handle.Init.AlphaInverted = DMA2D_REGULAR_ALPHA;  /* No Output Alpha Inversion*/  
  DMA2D_Handle.Init.RedBlueSwap   = DMA2D_RB_REGULAR;     /* No Output Red & Blue swap */   

  /*##-2- DMA2D Callbacks Configuration ######################################*/
  DMA2D_Handle.XferCpltCallback  = NULL;

  /*##-3- Foreground Configuration ###########################################*/
  DMA2D_Handle.LayerCfg[1].AlphaMode = DMA2D_REPLACE_ALPHA;
  DMA2D_Handle.LayerCfg[1].InputAlpha = 0xFF;

#if (JPEG_RGB_FORMAT == JPEG_ARGB8888)

  DMA2D_Handle.LayerCfg[1].InputColorMode = DMA2D_INPUT_ARGB8888;
  DMA2D_Handle.Init.ColorMode             = DMA2D_OUTPUT_ARGB8888;

#elif (JPEG_RGB_FORMAT == JPEG_RGB888)  

  DMA2D_Handle.LayerCfg[1].InputColorMode = DMA2D_INPUT_RGB888;
  DMA2D_Handle.Init.ColorMode             = DMA2D_OUTPUT_RGB888;

#elif (JPEG_RGB_FORMAT == JPEG_RGB565)  

  DMA2D_Handle.LayerCfg[1].InputColorMode = DMA2D_INPUT_RGB565;
  DMA2D_Handle.Init.ColorMode             = DMA2D_OUTPUT_RGB565;

#endif /* JPEG_RGB_FORMAT * */


  DMA2D_Handle.LayerCfg[1].InputOffset = 0;
  DMA2D_Handle.LayerCfg[1].RedBlueSwap = DMA2D_RB_REGULAR; /* No ForeGround Red/Blue swap */
  DMA2D_Handle.LayerCfg[1].AlphaInverted = DMA2D_REGULAR_ALPHA; /* No ForeGround Alpha inversion */

  DMA2D_Handle.Instance          = DMA2D;

  /* DMA2D Initialization */
  if(HAL_DMA2D_Init(&DMA2D_Handle) == HAL_OK)
  {
    if(HAL_DMA2D_ConfigLayer(&DMA2D_Handle, 1) == HAL_OK)
    {
            if (HAL_DMA2D_Start(&DMA2D_Handle, source, destination, PixelPerLine, NumberOfLine ) == HAL_OK)
            {
              // Polling For DMA transfer
           //   HAL_DMA2D_PollForTransfer(&DMA2D_Handle, 10000);       // 使用这个后,图片下半部分 不 能够显示字符  ??

              while (DMA2D->CR & DMA2D_CR_START)                           // 使用这个后,图片下半部分可以显示字符
              {
              }  
            }
    }
  }   
}



显示效果图片如下:

正常的竖屏显示,

竖屏.png


竖屏 180 度 显示图片如下:

竖屏180.png

这个竖屏 180度显示,字符汉字都已经正常显示了,唯独图片没有,需要修改哪里 ??

旋转180度显示图片的地址计算我是参考我的 图形显示参数修改的,显示图形任意方向显示是没有问题的

图片下半部分显示字符效果如下:
下半部分显示字符.png


图片下半部分 不 显示字符效果如下:

下半部分不显示字符.png








友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。