#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include "./pro_fb/fb.h"
#include "jpeg_disp.h"
extern struct fb_info info;
typedef u8_t u8_t_t;
//函数功能:解码图片
//返回值:成功解码之后图片像素点值数组,失败返回NULL
//参数jpegfile:jpeg文件路径;jpeginfo:该图片的信息(高、宽、深度)
u8_t *handle_jpeg(const char *jpegfile,struct fb_info *jpeginfo)
{
//1、解码图片
u8_t *buf24 = decode_jpeg(jpegfile,jpeginfo);
return buf24;
}
//显示图片
int jpeg_display(u8_t * buf24,int w,int h,int x,int y)
{
fb_t *buf;
struct fb_info newinfo;
newinfo.w = w;
newinfo.h = h;
#ifdef __BPP_32__
buf = rgb24to32(buf24,newinfo);
#elif __BPP_16__
buf = rgb24to16(buf24,newinfo);
#else
printf("you must defined __BPP_32__ or __BPP_16__.\n");
return -1;
#endif
printf("w = %d\th = %d\n",w,h);
int i,j;
//在(x,y)处显示图片
for(i=0;i<h;i++)
{
for(j=0;j<w;j++)
{
fb_pixel(x+j,y+i,buf[j+i*w]);
}
}
free(buf);
return 0;
}
//正常显示图片
int jpeg_normal_disp(const char *jpegfile,int x,int y)
{
struct fb_info jpeginfo;
u8_t* buf24 = handle_jpeg(jpegfile,&jpeginfo);
if(buf24 == NULL)
return -1;
//显示图片
jpeg_display(buf24,jpeginfo.w,jpeginfo.h,x,y);
return 0;
}
//对图像进行偏移操作,原像素点变为白色
//返回值:成功返回0,失败返回负数
//参数jpegfile : jpeg图片文件路径;x,y : 显示位置; dx:平移增量
int jpeg_tanslational_disp(const char *jpegfile,int x,int y,double offset)
{
//1.解码图片,获取像素点阵列
struct fb_info jpeginfo;
u8_t * buf24 = handle_jpeg(jpegfile,&jpeginfo);
if(buf24 == NULL)
return -1;
int newdw = jpeginfo.w + ceil(jpeginfo.w * offset);
#ifdef __DEBUG__
printf("out image size: %d * %d\n",newdw,jpeginfo.h);
#endif
u8_t *buf24_copy = (u8_t *)malloc(newdw*jpeginfo.h *3* sizeof(u8_t));
memset(buf24_copy,0xFF,newdw * jpeginfo.h * 3);
//2、处理平移之后各个像素点的值
int i,j,dx,dy;
for(i=0;i<jpeginfo.h;i++)
{
for(j = 0;j < jpeginfo.w;j++)
{
dx = i;
dy = ceil(offset *dx) + j;
memcpy(buf24_copy + (dx * newdw + dy) * 3,buf24 + (i * jpeginfo.w + j) * 3,3);
}
}
//3.在(x,y)处显示图片
jpeg_display(buf24_copy,newdw,jpeginfo.h,x,y);
free(buf24);
return 0;
}
//旋转图片函数
//返回值:成功返回0,失败返回负数
//参数jpegfile : jpeg图片文件路径;x,y : 显示位置; degree:旋转度数
int jpeg_rotate_disp(const char *jpegfile,int x,int y,int degree)
{
//1.解码图片,获取像素点阵列
struct fb_info jpeginfo;
u8_t *buf24 = handle_jpeg(jpegfile,&jpeginfo);
if(buf24 == NULL)
return -1;
//保证原图可以任意角度旋转的最小尺寸
int newLen=sqrt((double)jpeginfo.w* jpeginfo.w+ (double)jpeginfo.h*jpeginfo.h) + 10;
u8_t *buf24_copy = (u8_t *)malloc(newLen * newLen * 3);
memset(buf24_copy,0xFF,newLen*newLen*3);
//调用旋转函数
image_rotate(buf24,jpeginfo.w,jpeginfo.h,buf24_copy,newLen,newLen,degree,3);
//3.在(x,y)处显示图片
jpeg_display(buf24_copy,newLen,newLen,x,y);
free(buf24);
return 0;
}
//逆时针旋转到pbuf24_copy的中心,其它用0填充
//pSrc,srcW,srcH原图及其尺寸
//pDst,buf24_copyW,buf24_copyH旋转后图像及其尺寸
//旋转角度
//通道数
void image_rotate(unsigned char* pSrc,int srcW,int srcH, unsigned char* pDst,int buf24_copyW,int buf24_copyH,double degree,int nchannel)
{
int k;
double angle = degree * 3.1415926 / 180.; //旋转角度
double co=cos(angle); //余弦
double si=sin(angle); //正弦
int rotateW,rotateH; //旋转后图像的高宽
int srcdwStep=srcW*nchannel;//宽度步长
int buf24_copyWisthStep=buf24_copyW*nchannel;
int x,y;
int xMin,xMax,yMin,yMax;
int xOff,yOff; //偏移
double xSrc=0.;
double ySrc=0.; //变换后图像的坐标在原图中的坐标
//临时变量
fb_t valueTemp=0.;
fb_t a1,a2,a3,a4;
//计算旋转后的坐标范围
rotateH=srcW*fabs(si)+srcH*fabs(co);
rotateW=srcW*fabs(co)+srcH*fabs(si);
//计算偏移
xOff=buf24_copyW/2;
yOff=buf24_copyH/2;
yMin=(buf24_copyH-rotateH)/2.;
yMax=yMin+rotateH+1; //加1
xMin=(buf24_copyW-rotateW)/2.;
xMax=xMin+rotateW+1;
for (y=yMin;y<=yMax;y++)
{
for (x=xMin;x<=xMax;x++)
{
//求取在原图中的坐标
ySrc=si*(double)(x-xOff)+co*(double)(y-yOff)+(double)((int)(srcH/2));
xSrc=co*(double)(x-xOff)-si*(double)(y-yOff)+(double)((int)(srcW/2));
//如果在原图范围内
if (ySrc>=0. && ySrc<srcH-0.5 && xSrc>=0. && xSrc<srcW-0.5)
{
//插值
int xSmall=floor(xSrc);
int xBig=ceil(xSrc);
int ySmall=floor(ySrc);
int yBig=ceil(ySrc);
for (k=0;k<nchannel;k++)
{
a1=(xSmall>=0 && ySmall>=0 ? pSrc[ySmall*srcdwStep+xSmall*nchannel+k]:0);
a2=(xBig<srcW && ySmall>=0 ? pSrc[ySmall*srcdwStep+xBig*nchannel+k]:0);
a3=(xSmall>=0 && yBig<srcH ? pSrc[yBig*srcdwStep+xSmall*nchannel+k]:0);
a4=(xBig<srcW && yBig<srcH ? pSrc[yBig*srcdwStep+xBig*nchannel+k]:0);
double ux=xSrc-xSmall;
double uy=ySrc-ySmall;
//双线性插值
valueTemp=(1-ux)*(1-uy)*a1+(1-ux)*uy*a3+(1-uy)*ux*a2+ux*uy*a4;
pDst[y*buf24_copyWisthStep+x*nchannel+k]=floor(valueTemp);
}
}
}
}
}
int jpeg_nearext_disp(const char *jpegfile,int x,int y,int w,int h)
{
//1.解码图片,获取像素点阵列
struct fb_info jpeginfo;
u8_t *buf24 = handle_jpeg(jpegfile,&jpeginfo);
if(buf24 == NULL)
return -1;
//保证原图可以任意角度旋转的最小尺寸
u8_t *buf24_copy = (u8_t *)malloc(w * h * 3);
//使用最近邻插值计算放大函数
nearest_insert(buf24,jpeginfo.w,jpeginfo.h, buf24_copy, w, h,3);
//3.在(x,y)处显示图片
jpeg_display(buf24_copy,w,h,x,y);
free(buf24_copy);
return 0;
}
//最近邻插值计算
//返回值:成功返回0,失败返回负数
//参数:
//pSrc:原图像像素点值阵列; sw,sh:原图像高度和宽度
//pDrc:目标图像像素点值阵列; dw,dh:目标图像高度和宽度
int nearest_insert(u8_t *buf24,int sw,int sh, u8_t *buf24_copy, int dw, int dh,int channel)
{
//sh方向上的比值
double fx = (double)sh / (double)dh;
//sw方向上的比值
double fy = (double)sw / (double)dw;
int x,y,k;
for (x = 0; x < dh; x++)
{
for(y = 0; y < dw; y++)
{
for (k = 0; k <channel; k++)
{
int out = (x * dw + y )* channel + k;
int ori = ((int)(fx * x) * sw + (int)(fy * y)) * channel + k;
buf24_copy[out] = buf24[ori];
}
}
}
return 0;
}
int jpeg_biline_disp(const char *jpegfile,int x,int y,int w,int h)
{
//1.解码图片,获取像素点阵列
struct fb_info jpeginfo;
u8_t *buf24 = handle_jpeg(jpegfile,&jpeginfo);
if(buf24 == NULL)
return -1;
//保证原图可以任意角度旋转的最小尺寸
u8_t *buf24_copy = (u8_t *)malloc(w * h * 3);
//使用最近邻插值计算放大函数
biliner_insert(buf24,jpeginfo.w,jpeginfo.h, buf24_copy, w, h,3);
//3.在(x,y)处显示图片
if(x > info.w)
x = 1023;
if(y >info.h)
y = 720;
jpeg_display(buf24_copy,w,h,x,y);
free(buf24_copy);
return 0;
}
int biliner_insert(u8_t *buf24,int sw,int sh, u8_t *buf24_copy, int dw, int dh,int channel)
{
//sh方向上的比值
double fx = (double)sh/ (double)dh;
//sw方向上的比值
double fy = (double)sw / (double)dw;
int x,y,k;
for (x = 0; x < dh; x++)
{
for(y = 0; y < dw; y++)
{
//对于目标图像(x, y),实际映射到原图的坐标为(fx * x, fy * y),但是若为小数,原图并不存在该店,因此近似为(i, j)
int i = fx * x;
int j = fy * y;
int out = (x * dw+ y) * channel;
//找到四个领域的下标
int ori1 = (i * sw+ j) * channel;
int ori2 = (i * sw + (j + 1)) * channel;
int ori3 = ((i + 1) * sw + j) * channel;
int ori4 = ((i + 1) * sw + (j + 1)) * channel;
for (k = 0; k <channel; k++)
{
float u = (float)x * fx - i;
float v = (float)y * fy - j;
buf24_copy[out + k] = buf24[
小_阳仔
- 粉丝: 27
- 资源: 22
最新资源
- 基于阿里Dubbo框架的服务切换工具资料齐全+详细文档.zip
- 基于大规模生产实践的,适合公司内部二开迭代dubbo的模板资料齐全+详细文档.zip
- 基于大众点评CAT(v1.3.6)监控的扩展,主要是跨服务的消息树(dubbo、http方式)、Cache以及DB监控等资料齐全+详细文档.zip
- 基于将dubbo协议转http的网关资料齐全+详细文档.zip
- 基于分布式微服务架构(在线电影),技术架构有SpringBoot、SpringCoud、dubbo、mybatis-plus、Druid,采用前后端分离方式进行
- 基于微服务架构的班车预约系统,第一个版本:springboot+mybatis+dubbo+mysql+redis等。第二个版本:spring-cloud重构,
- 滚动轴承故障诊断MATLAB程序:快速谱峭度、谱峭度+包络谱分析 滚动轴承故障诊断是机械工程领域的一个重要研究方向 滚动轴承是一种常见的机械元件,用于支撑和转动机械装置中的轴 然而,由于长时间使用或其
- matlab GUI界面设计
- VSC下垂控制策略仿真模型,支持MATLAB2014a及以上版本
- wechat4.0多开工具
- 课程大作业2:视觉功能库封装 作业内容: 利用预训练模型,基于1ibsophon(tpu-runtime)实现一个视觉功能(目标检测)的库 作业要求: 1)提交 patch 到tpu-mli 工程
- 学习笔记整理成语音.docx
- 毕设和企业适用springboot智能语音识别平台类及物流追踪系统源码+论文+视频.zip
- PPT_20241224_090531.pptx
- ai提示规则.txt啊啊啊
- Visual Studio Code的测试功能详细介绍.pdf
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈