硬件准备
ADSP-EDU-BF533:BF533开发板
 AD-HP530ICE:ADI DSP仿真器
软件准备
Visual DSP++软件
硬件链接

功能介绍
代码实现了图像缩放处理,代码运行时,会通过文件系统打开工程文件根目下" …/ImageView"路径中的 testin.bmp 文件,进行图像的缩放处理后把图片保存到工程文件根目下" …/ImageView"路径中的 testout.bmp 文件,并且将处理后的图片显示到液晶屏上。例子中的算法只支持尺寸为 480*272 的 24bit 的 bmp 图片,可以根据自己的需要自行调整。
代码使用说明
 funct.c 中的 Resize(BMPIMAGE* img,float fXZoomRatio, floatfYZoomRatio)
 该函数是将读取的图像进行缩放处理。
BMPIMAGE * 图像结构体指针
 float fXZoomRatio 水平缩放系数 大于 1 放大,小于 1 缩小
 float fYZoomRatio 垂直缩放系数 大于 1 放大,小于 1 缩小
在 main.c 文件中定义了一个#define LCD_VIEW_ENABLE 宏开关,如果不需要将处理后的图片显示在液晶屏上,只需将这个宏开关注释掉
代码实验步骤
- 将工程文件根目下的 ImageView 文件夹内存放一个名为 testin.bmp 的图像文件,该文件尺寸为 480*272 的24bit 的 bmp 图片(默认已存一幅测试图片)。
- 打开工程文件 BF53x_Resize.dpj,编译并运行代码
- 等待图像处理,处理完成之后会在液晶屏上显示处理后的图片,并在工程文件根目下的 ImageView 文件夹内生成一个处理后名为 testout.bmp 图片。
代码实验结果
1.液晶屏上显示处理后的图片,缩小后的图片显示在液晶屏的中心位置,放大后在图片的中心位置取液晶屏一样的图片显示,在液晶屏上显示的前提是 fXZoomRatio fYZoomRatio 同时大于 1 或者同时小于 1, 否则不会在液晶屏上显示, 只能通过文件查看处理后的图片。
2.在工程文件根目下的 ImageView 文件夹中查看处理后名为 testout.bmp 图片。
程序源码
bmp.c
#include<stdio.h>
 #include “bmp.h”
/********************************************************
- 函数名 : OpenBmpFile
- 函数功能 : 以二进制形式打开计算机硬盘BMP图像文件
- 函数参数 : const char * 图像文件名称
-  BMPIMAGE * 图像结构体指针
- 函数返回值 :FALSE 打开图像文件失败
-  TRUE 打开图像文件成功
/
 int OpenBmpFile(const char filename, BMPIMAGE img) {
 if((img->bmpfile = fopen(filename, “rb”)) == NULL)
 {
 printf(“open file is Failure\n\r”);
 return FALSE;
 }
 return TRUE;
 }
 /**
- 函数名 : writeBmpFile
- 函数功能 : 将二进制图像数据保存到计算机硬盘中
- 函数参数 : const char * 图像文件名称
-  BMPIMAGE * 图像结构体指针
- 函数返回值 :FALSE 保存图像文件失败
-  TRUE 保存图像文件成功
******************************************************/
 int writeBmpFile(const char filename,const BMPIMAGE img) {
FILE *fp;
unsigned int i,j;
unsigned char tempData, *pData;
unsigned int tempHeight;
unsigned int tempWidth;
tempHeight = img->infohead.BiHeight>>1;
tempWidth = img->infohead.BiWidth*3;
pData = img->imgbuf;
for(i = 0; i < img->imagesize; i = i + 3) {
	tempData = pData[i];
	pData[i] = pData[i + 2];
	pData[i + 2] = tempData;
}
for(i=0;i<tempHeight;i++)
{
	for(j=0;j<tempWidth;j++)
	{
		tempData = pData[(img->infohead.BiHeight-1-i)*tempWidth+j];
		pData[(img->infohead.BiHeight-1-i)*tempWidth+j] = pData[i*tempWidth+j];
		pData[i*tempWidth+j] = tempData;
	}
}
if((fp = fopen(filename, "wb")) == NULL)
{
	printf("seek file is Failure\n\r");
	return FALSE;
}	
fwrite(&img->filehead, 1, 2, fp);
fwrite(&img->filehead.bfSize, 1, 12, fp);
fwrite(&img->infohead, 1, 40, fp);
fwrite(img->imgbuf, 1, img->imagesize, fp);
fclose(fp);
fclose(img->bmpfile);
return TRUE;
}
 /********************************************************
- 函数名 : GetBmpHeader
- 函数功能 : 读取BMP文件头
- 函数参数 : BMPIMAGE * 图像结构体指针
- 函数返回值 :FALSE 读取BMP文件头失败
-  TRUE 读取BMP文件头成功
*******************************************************/
 int GetBmpHeader(BMPIMAGE img) {
 unsigned char headbuffer[INFOHEADSIZE]; 
 BMPFILEHEAD filehead = &img->filehead;
 BMPINFOHEAD infohead = &img->infohead;
 if (fread(headbuffer, 1, FILEHEADSIZE, img->bmpfile) != FILEHEADSIZE) {
 return FALSE;
 }
 img->filehead.bfType[0] = headbuffer[0];
 img->filehead.bfType[1] = headbuffer[1];
 if ((unsigned short )&filehead->bfType[0] != (0x4D42)) { / ‘BM’ /
 printf(“file is not bmp\n\r”);
 return FALSE; / not bmp image/
 }
 memcpy(&filehead->bfSize, &headbuffer[2], 4);
 memcpy(&filehead->bfOffBits, &headbuffer[10], 4);
 if(fseek(img->bmpfile, FILEHEADSIZE, SEEK_SET)) {
 return FALSE;
 }
 if (fread(headbuffer, 1, INFOHEADSIZE, img->bmpfile) != INFOHEADSIZE) {
 return FALSE;
 }
 memcpy(&infohead->BiSize, &headbuffer[0], 4);
 memcpy(&infohead->BiWidth, &headbuffer[4], 4);
 memcpy(&infohead->BiHeight, &headbuffer[8], 4);
 memcpy(&infohead->BiPlanes, &headbuffer[12], 2);
 memcpy(&infohead->BiBitCount, &headbuffer[14], 2);
 memcpy(&infohead->BiCompression, &headbuffer[16], 4);
 memcpy(&infohead->BiSizeImage, &headbuffer[20], 4);
 memcpy(&infohead->BiXpelsPerMeter, &headbuffer[24], 4);
 memcpy(&infohead->BiYpelsPerMeter, &headbuffer[28], 4);
 memcpy(&infohead->BiClrUsed, &headbuffer[32], 4);
 memcpy(&infohead->BiClrImportant, &headbuffer[36], 4);
 if(infohead->BiPlanes != 1) {
 return FALSE;
 }
 if(infohead->BiBitCount !=24) {
 return FALSE;
 } 
 if(infohead->BiCompression != BI_RGB) {
 return FALSE;
 }
 GetImageSize(img);
 return TRUE;
 }
/********************************************************
- 函数名 : GetImageSize
- 函数功能 : 获取BMP文件大小
- 函数参数 : BMPIMAGE * 图像结构体指针
- 函数返回值 :void 
 ********************************************************/
 void GetImageSize(BMPIMAGE *img) {
 img->imagesize = img->infohead.BiHeight * WIDTHBYTES(img->infohead.BiWidth * img->infohead.BiBitCount);
 }
/********************************************************
- 函数名 : ReadBMPData
- 函数功能 : 读取BMP数据缓冲区
- 函数参数 : BMPIMAGE * 图像结构体指针
- 函数返回值 :FALSE 读取BMP数据失败
-  TRUE 读取BMP数据成功
*******************************************************/
 int ReadBMPData(const BMPIMAGE img) {
 unsigned int pitch = WIDTHBYTES(img->infohead.BiWidth * img->infohead.BiBitCount);
 unsigned int readnum = 0;
 int i, j, k;
 unsigned char m_temp;
 unsigned char *p_tmp, *p_tmp_cur;
 unsigned char tempData, pData;
 unsigned int index_data;
 pData = img->imgbuf;
 if(fseek(img->bmpfile, img->filehead.bfOffBits, SEEK_SET)) {
 return FALSE;
 }
 p_tmp = NULL;
 p_tmp = (unsigned char )malloc(pitch * img->infohead.BiHeight);
 if(p_tmp != NULL) {
 readnum = fread(p_tmp, 1, pitch * img->infohead.BiHeight, img->bmpfile);
 p_tmp_cur = p_tmp;
 for(i = img->infohead.BiHeight - 1; i >= 0; i–, p_tmp_cur += pitch) {
 memcpy(&img->imgbuf[ipitch], p_tmp_cur, pitch);
 }
 }
 else {
 for(i = img->infohead.BiHeight - 1; i >= 0; i–) {
 readnum += fread(&img->imgbuf[ipitch], 1, pitch, img->bmpfile);
 }
 } 
 for(index_data = 0; index_data < img->imagesize; index_data = index_data + 3) {
 tempData = pData[index_data];
 pData[index_data] = pData[index_data + 2];
 pData[index_data + 2] = tempData;
 }
 if(p_tmp != NULL) {
 free(p_tmp);
 }
 return (readnum == img->imagesize); 
 }
/********************************************************
- 函数名 : Allocbuf
- 函数功能 : 分配图像缓冲区
- 函数参数 : BMPIMAGE * 图像结构体指针
- 函数返回值 :FALSE 分配图像缓冲区失败
-  TRUE 分配图像缓冲区成功
/
 int Allocbuf(BMPIMAGE img) {
 if((img->imgbuf = malloc(img->imagesize)) == NULL)
 return FALSE;
 return TRUE;
 }
 /*
- 函数名 : Freebuf
- 函数功能 : 释放图像缓冲区
- 函数参数 : BMPIMAGE * 图像结构体指针
- 函数返回值 :void
 *******************************************************/
 void Freebuf(BMPIMAGE img) {
 if(img->imgbuf != NULL)
 free(img->imgbuf);
 img->imgbuf = NULL;
 }
cpu.c
#include <cdefBF533.h>
 #include “cpu.h”
void Init_Timers0(int dat)
 {
 *pTIMER0_CONFIG = 0x0019;
 *pTIMER0_WIDTH = dat;
 *pTIMER0_PERIOD = 2000;
 }
void Enable_Timers0(void)
 {
 *pTIMER_ENABLE|= 0x0001;
 asm(“ssync;”);
 }
void Disable_Timers0(void)
 {
 *pTIMER_DISABLE |= 0x0001; 
 }
void Set_PLL(int pmsel,int pssel)
 {
 int new_PLL_CTL; 
 *pPLL_DIV = pssel;
 asm(“ssync;”);
 new_PLL_CTL = (pmsel & 0x3f) << 9; 
 *pSIC_IWR |= 0xffffffff;
 if (new_PLL_CTL != *pPLL_CTL)
 {
 *pPLL_CTL = new_PLL_CTL;
 asm(“ssync;”);
 asm(“idle;”);
 }
 }
void Init_SDRAM(void)
 {
 *pEBIU_SDRRC = 0x00000817; 
 *pEBIU_SDBCTL = 0x00000013;
 *pEBIU_SDGCTL = 0x0091998d;
 ssync(); 
 }
void Init_EBIU(void)
 {
 *pEBIU_AMBCTL0 = 0x7bb07bb0;
 *pEBIU_AMBCTL1 = 0x7bb07bb0;
 *pEBIU_AMGCTL = 0x000f;
 }
fun.c
#include “bmp.h”
/********************************************************
- 函数名 : Resize
- 函数功能 : 图像缩放处理
-  
  -  
   
    函数参数 : BMPIMAGE * 图像结构体指针
    
   
- float fXZoomRatio 水平缩放系数
- float fYZoomRatio 垂直缩放系数
 
- 函数返回值 :FALSE 处理失败
-  TRUE 处理成功
*******************************************************/
 int Resize(BMPIMAGE img,float fXZoomRatio, float fYZoomRatio)
 {
 // 源图像的宽度和高度
 long lWidth;
 long lHeight;
// 缩放后图像的宽度和高度
long	lNewWidth;
long	lNewHeight;
// 缩放后图像的宽度(lNewWidth',必须是4的倍数)
long	lNewLineBytes;
// 指向源象素的指针
unsigned char	*lpSrc;	
// 指向缩放图像对应象素的指针
unsigned char	*lpDst;
unsigned char *lpDIBBits = img->imgbuf;
unsigned char *lpNewDIBBits;	// 循环变量(象素在新DIB中的坐标)	
long	i,k,j;
// 象素在源DIB中的坐标
long	i0;
long	j0;
// 图像每行的字节数
long lLineBytes;
lWidth = img->infohead.BiWidth;
// 获取图像的高度
lHeight = img->infohead.BiHeight;
lLineBytes= WIDTHBYTES(lWidth * 24);
// 计算缩放后的图像实际宽度
// 此处直接加0.5是由于强制类型转换时不四舍五入,而是直接截去小数部分
lNewWidth = (long) (lWidth * fXZoomRatio + 0.5);
// 计算新图像每行的字节数
lNewLineBytes = WIDTHBYTES(lNewWidth * 8*3);
// 计算缩放后的图像高度
lNewHeight = (long) (lHeight * fYZoomRatio + 0.5);
lpNewDIBBits = (unsigned char*)malloc(lNewLineBytes*lNewHeight);
if(lpNewDIBBits == NULL)
	return FALSE;	
// 针对图像每行进行操作
for(i = 0; i < lNewHeight; i++)
{
	// 针对图像每列进行操作
	for(j = 0; j < lNewWidth; j++)
	{
		for(k=0;k<3;k++)
		{
			// 指向新DIB第i行,第j个象素的指针
			// 注意此处宽度和高度是新DIB的宽度和高度
			lpDst = (unsigned char *)lpNewDIBBits + lNewLineBytes * (lNewHeight - 1 - i) + 3*j + k;
		
			// 计算该象素在源DIB中的坐标
			i0 = (long) (i / fYZoomRatio + 0.5);
			j0 = (long) (j / fXZoomRatio + 0.5);
			//判断是否在源图范围内
			if( (j0 >= 0) && (j0 < lWidth) && (i0 >= 0) && (i0 < lHeight))
			{
				// 指向源DIB第i0行,第j0个象素的指针
				lpSrc = (unsigned char *)lpDIBBits + lLineBytes * (lHeight - 1 - i0) + 3*j0 + k;
				// 复制象素
				*lpDst = *lpSrc;
			}
			else
			{
				// 对于源图中没有的象素,直接赋值为255
				* ((unsigned char*)lpDst) = 255;
			}
		}
	}		
}
free(img->imgbuf);
img->imgbuf = lpNewDIBBits;
img->infohead.BiWidth = lNewWidth;
img->infohead.BiHeight = lNewHeight;
img->imagesize = lNewLineBytes*lNewHeight;
return TRUE;
}
main.c
#include <cdefBF533.h>
 #include “cpu.h”
 #include “tftlcd.h” 
 #include “bmp.h” 
 #include “funct.h”
#define INFILEADDR “…/ImageView/testin.bmp”
 #define OUTFILEADDR “…/ImageView/testout.bmp”
 #define LCD_VIEW_ENABLE
 /在液晶屏上显示必须xzoom yzoom同时大于1或者同时小于1,
 否则不会在液晶屏上显示,但是可以输出处理后的图像/
 float xzoom = 2; //水平缩放系数
 float yzoom = 2; //垂直缩放系数
int main(void)
 {
 BMPIMAGE bmpimage;
 Set_PLL(16,4);
 Init_EBIU();
 Init_SDRAM(); 
 LCDBK_Disable(); 
 if(!OpenBmpFile(INFILEADDR,&bmpimage))
 return FALSE;
 if(!GetBmpHeader(&bmpimage))
 return FALSE;
 if(!Allocbuf(&bmpimage))
 return FALSE;
 if(!ReadBMPData(&bmpimage))
 return FALSE;
/* 图像缩放处理			*/
if(!Resize(&bmpimage,xzoom,yzoom))
	return FALSE;	
#ifdef LCD_VIEW_ENABLE
 Enable_Timers0();
 RGB888_RGB565(&bmpimage,(void*)DisplayBuffer_565,xzoom,yzoom);
 #endif
if(!writeBmpFile(OUTFILEADDR,&bmpimage))
	return FALSE;
#ifdef LCD_VIEW_ENABLE 
 InitDMA();
 InitPPI();
 InitTimer();
 PPI_TMR_DMA_Enable();
 LCD_Enable();
 LCDBK_Enable();
 Init_Timers0(1999);//1~1999 控制背光亮度
 Enable_Timers0();
 while(1);
 #endif
 }
lcd.c
#include <cdefBF533.h>
 #include “tftlcd.h” 
 #include “cpu.h”
section(“sdram0_bank1”) unsigned char DisplayBuffer_565[272][1440] ;
void InitDMA(void)
 {
 int addr;
 addr = &DisplayBuffer_565;
 addr -= 1920;
 *pDMA0_START_ADDR = addr;
*pDMA0_X_COUNT = 480;
*pDMA0_X_MODIFY = 2;
*pDMA0_Y_COUNT = 286;
*pDMA0_Y_MODIFY = 2;	
*pDMA0_CONFIG = 0x1034;
}
void InitPPI(void)
 {
 *pPPI_CONTROL = 0x781e; 
 *pPPI_DELAY = 0; 
 *pPPI_COUNT = 479; 
 *pPPI_FRAME = 286; 
 }
void InitTimer(void)
 {
 *pTIMER1_PERIOD = 525;
 *pTIMER1_WIDTH = 41;
 *pTIMER1_CONFIG = 0x00a9;
 *pTIMER2_PERIOD = 150150;
 *pTIMER2_WIDTH = 5250;
 *pTIMER2_CONFIG = 0x00a9;
 }
void PPI_TMR_DMA_Enable(void)
 {
 *pDMA0_CONFIG |= 0x1;
 asm(“ssync;”);
 InitTimer(); 
 *pPPI_CONTROL |= 0x1; 
 asm(“ssync;”);
 *pTIMER_ENABLE|= 0x0006;
 asm(“ssync;”);
 }
void PPI_TMR_DMAR_Disable(void)
 {
 *pDMA0_CONFIG &= (~0x1);
 *pPPI_CONTROL &= (~0x1);
 }
void RGB888_RGB565( BMPIMAGE* img, unsigned char dst,float zox,float zoy)
 {
 int i = 0;
 int j = 0;
 int m=0;
 int oxsize;
 int oysize;
 int tempsize;
 if((zox>=1)&&(zoy>=1))
 {
 oxsize = (3(img->infohead.BiWidth-480))/2;
 oysize = (img->infohead.BiHeight-272)/2;
 tempsize = img->infohead.BiWidth3; 
 oysize = oysizetempsize;
 for(i=0;i<272;i++)
 {
 for(j=0;j<1440;j+=3)
 {
 dst[m+1] = img->imgbuf[oxsize+oysize+itempsize+j+2] &0xf8;
 dst[m+1] |= ((img->imgbuf[oxsize+oysize+itempsize+j+1]>>5) & 0x07);//GH
 dst[m] = ((img->imgbuf[oxsize+oysize+itempsize+j+1]<<3) & 0xe0); //GL
 dst[m] |= ((img->imgbuf[oxsize+oysize+itempsize+j]>>3) &0x1f); //r
 m += 2; 
 }
 }
 }
 else if(zox<1&&zoy<1)
 {
 oxsize = 480-img->infohead.BiWidth;
 tempsize = img->infohead.BiWidth*3;
 oysize = 272 - img->infohead.BiHeight;
 oysize = oysize/2;
 for(i=0;iinfohead.BiHeight;i++)
 {
 m=0;
 for(j=0;j<tempsize;j+=3)
 {
 dst[(oysize+i)960+m+oxsize+1] = img->imgbuf[itempsize+j+2]&0xf8;
 dst[(oysize+i)960+m+oxsize+1] |=((img->imgbuf[itempsize+j+1]>>5) & 0x07); 
 dst[(oysize+i)960+m+oxsize] = ((img->imgbuf[itempsize+j+1]<<3) & 0xe0); //GL
 dst[(oysize+i)960+m+oxsize] |= ((img->imgbuf[itempsize+j]>>3) &0x1f); //r
 m += 2; 
 }
 }
 }
 else
 {
 printf(“LCD view Failure\n\r”);
 LCDBK_Disable();
}
}

![[附源码]计算机毕业设计二手书店设计论文Springboot程序](https://img-blog.csdnimg.cn/9cc84da08ba94b45805bb8541bcf389a.png)

















