案例三-使用 jpeg库 显示图片到液晶屏

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include "jpeglib.h"
#include <stdbool.h>
#include <stdlib.h>
 
int *p;
 
void show_jpeg(const char *jpeg_file)
{
    //jpeg图片的显示
    //创建jpeg对象分配空间并初始化
    struct jpeg_decompress_struct cinfo;
    //创建jpeg错误信息结构体
    struct jpeg_error_mgr jpeg_err;
    //将错误信息结构体绑定对象
    cinfo.err = jpeg_std_error(&jpeg_err);
    jpeg_create_decompress(&cinfo);
 
    FILE *fp = fopen(jpeg_file, "r+");
    if (fp == NULL)
    {
        perror("fopen");
        return;
    }
    //指定解压缩源
    jpeg_stdio_src(&cinfo, fp);
    //获取文件信息
    jpeg_read_header(&cinfo, true);
    //为解压缩设定参数,比如,图像大小,宽高
    //2880 1920
    int n = 1;
    while(cinfo.image_width/n>800 || cinfo.image_height/n>480)
    {
        n*=2;
    }
    cinfo.scale_num = 1;
    cinfo.scale_denom = n;
    printf("解压缩之前:宽度 %d 高度 %d\n", cinfo.image_width, cinfo.image_height);
    //开始解压缩
    jpeg_start_decompress(&cinfo);
    printf("解压缩之后:宽度 %d 高度 %d\n", cinfo.output_width, cinfo.output_height);
 
    int start_x = (800-cinfo.output_width)/2;
    int start_y = (480-cinfo.output_height)/2;
    //取出数据
    //720 480
    // 一行一行的去取
    char r, g, b;
    int color;
    char *buffer = malloc(cinfo.output_width*cinfo.output_components);
    while(cinfo.output_scanline < cinfo.output_height)
    {
        jpeg_read_scanlines(&cinfo, (JSAMPARRAY)&buffer, 1);
        for (int y = 0, x = 0; x < cinfo.output_width; ++x)
        {
            r = buffer[y++];
            g = buffer[y++];
            b = buffer[y++];
            color = r<<16 |g<<8 |b;
            *(p+(cinfo.output_scanline-1+start_y)*800+x+start_x) = r<<16 |g<<8 |b;
        }
    }
    //解压缩完毕
    jpeg_finish_decompress(&cinfo);
    //释放资源
    fclose(fp);
    jpeg_destroy_decompress(&cinfo);
    free(buffer);
}
 
int main(int argc, char const *argv[])
{
    if (argc != 2)
    {
        printf("./show_jpeg <file>\n");
        return -1;
    }
    //  1、打开液晶屏,做内存映射
    int lcd_fd = open("/dev/fb0", O_RDWR);
    if (lcd_fd == -1)
    {
        perror("open lcd");
        return -1;
    }
 
    //内存映射
    p = mmap(NULL, 800*480*4, PROT_READ|PROT_WRITE, MAP_SHARED, lcd_fd, 0);
    if (p == (void *)-1)
    {
        perror("mmap");
        return -1;
    }
    show_jpeg(argv[1]);
 
    munmap(p, 800*480*4);
    close(lcd_fd);
 
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值