libjpeg和ligpng的安装和使用

最近在做点阵屏的显示,程序需要从图片文件中读取像素数据,于是研究了一下libjpeg库的使用。

下载

http://www.ijg.org/
https://sourceforge.net/projects/libpng/files/libpng16/1.6.34/

交叉编译

1.解压jpegsrc.v9b.tar.gz
tar -xvf jpegsrc.v9b.tar.gz
2. cd jpeg-9b
3. ./configure --host=KaTeX parse error: Expected 'EOF', got '&' at position 76: …static 4. make &̲& make install …PWD/install --prefix=aarch64-linux --enable-shared --enable-static
7. make && make install

编译完成后在install文件夹下得到库文件
在这里插入图片描述
将include的头文件拷到编译器的头文件目录,然后链接对应的库即可。

编写程序

我写了一个类

#ifndef BMAT_H
#define BMAT_H

#include <jpeg/jpeglib.h>
#include <jpeg/jerror.h>
#include <png/png.h>
#include <setjmp.h>
#include <stdio.h>
#include <cstring>

struct Color {
  Color() : r(0), g(0), b(0) {}
  Color(uint8_t rr, uint8_t gg, uint8_t bb) : r(rr), g(gg), b(bb) {}
  uint8_t r;
  uint8_t g;
  uint8_t b;
};

template <class T>
class BMat {
public:

    BMat() : with(0), hight(0), mat(NULL) {
    }

    BMat(unsigned int w_, unsigned int h_) : with(w_), hight(h_) {
        mat = new T*[with];
        for (int i = 0; i < with; i++)
            mat[i] = new T[hight];
    }

    virtual ~BMat() {
        for (int i = 0; i < with; i++) {
            delete mat[i];
        }
        delete mat;
    }

    T* operator[](int x) {
        if (x < with)
            return mat[x];
    }
    
    /*
     * Returns the number of rows of the matrix. 
     * If the matrix saves an image, it returns the height of the image.
     */
    unsigned int rows(){
        return hight;
    }
    
    unsigned int cols(){
        return with;
    }

    /*
     * Loading image data from the image file is saved in the matrix. 
     * Currently, only RGB color system is supported, 
     * and JPEG and PNG file formats are supported.
     */
    bool imread(const char *file) {
        char *p = strstr(file, ".");
        if (strncmp(p, ".jpg", 4) == 0) {
            return readjpeg(file);
        } else if (strncmp(p, ".png", 4) == 0) {
            unsigned char checkheader[8];
            FILE *fp = fopen(file, "rb");
            if(fp == NULL){
                fprintf(stderr, "%s open failed\n", file);
                return false;
            }
            if(fread(checkheader, 1, PNG_BYTES_TO_CHECK, fp) != PNG_BYTES_TO_CHECK){
                fprintf(stderr, "checkheader failed\n");
                fclose(fp);
                return false;
            }
            if(readpng(&fp)){
                fclose(fp);
                return true;
            }else{
                fclose(fp);
                return false;
            }
        }
        return false;
    }
protected:

    struct error_mgr {
        struct jpeg_error_mgr pub;
        jmp_buf setjmp_buffer;
    };

    METHODDEF(void) my_error_exit(j_common_ptr cinfo) {
        struct error_mgr *myerr = (struct error_mgr *) cinfo->err;
        (*cinfo->err->output_message) (cinfo);
        longjmp(myerr->setjmp_buffer, 1);
    }

    /*Reading image data from JPG image file*/
    bool readjpeg(const char *file) {
        struct jpeg_decompress_struct cinfo;
        struct error_mgr jerr;
        FILE *infile;
        JSAMPARRAY buffer;
        int row_stride;

        if ((infile = fopen(file, "rb")) == NULL) {
            fprintf(stderr, "can't open %s\n", file);
            return false;
        }
        cinfo.err = jpeg_std_error(&jerr.pub);
        jerr.pub.error_exit = my_error_exit;
        if (setjmp(jerr.setjmp_buffer)) {
            jpeg_destroy_decompress(&cinfo);
            fclose(infile);
            return false;
        }
        jpeg_create_decompress(&cinfo);
        jpeg_stdio_src(&cinfo, infile);
        (void) jpeg_read_header(&cinfo, TRUE);
        if (!mat) {
            with = cinfo.image_width;
            hight = cinfo.image_height;
            mat = new Color*[with];
            for (int i = 0; i < with; i++)
                mat[i] = new Color[hight];
        } else {
            for (int i = 0; i < with; i++) {
                delete mat[i];
            }
            delete mat;
            with = cinfo.image_width;
            hight = cinfo.image_height;
            mat = new Color*[with];
            for (int i = 0; i < with; i++)
                mat[i] = new Color[hight];
        }
        (void) jpeg_start_decompress(&cinfo);
        row_stride = cinfo.output_width * cinfo.output_components;
        buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) & cinfo, JPOOL_IMAGE, row_stride, 1);

        for (int j = 0; j < hight; j++) {
            (void) jpeg_read_scanlines(&cinfo, buffer, 1);
            for (int i = 0; i < with; i++) {
                mat[i][j].r = buffer[0][(i+1) * 3 + 0];
                mat[i][j].g = buffer[0][(i+1) * 3 + 1];
                mat[i][j].b = buffer[0][(i+1) * 3 + 2];
            }
        }

        (void) jpeg_finish_decompress(&cinfo);
        jpeg_destroy_decompress(&cinfo);
        fclose(infile);
        return true;
    }

    /*Reading image data from PNG image file*/
    bool readpng(FILE **fpp) {
        png_structp png_ptr;
        png_infop   info_ptr;
        
        png_ptr = png_create_read_struct(
                PNG_LIBPNG_VER_STRING,
                NULL, NULL, NULL);
        info_ptr = png_create_info_struct(png_ptr);
        
        setjmp(png_jmpbuf(png_ptr));
        rewind(*fpp);
        
        png_init_io(png_ptr, *fpp);
        png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND, 0);
        
        int channels, color_type;
        png_byte bit_depth;
        channels = png_get_channels(png_ptr, info_ptr);
        color_type = png_get_color_type(png_ptr, info_ptr);
        bit_depth = png_get_bit_depth(png_ptr, info_ptr);
        with = png_get_image_width(png_ptr, info_ptr);
        hight = png_get_image_height(png_ptr, info_ptr);
        
        if (!mat) {
            mat = new Color*[with];
            for (int i = 0; i < with; i++)
                mat[i] = new Color[hight];
        } else {
            for (int i = 0; i < with; i++) {
                delete mat[i];
            }
            delete mat;
            mat = new Color*[with];
            for (int i = 0; i < with; i++)
                mat[i] = new Color[hight];
        }
        
        png_bytepp row_pointers;
        row_pointers = png_get_rows(png_ptr, info_ptr);
        if(channels == 4 || 
                color_type == PNG_COLOR_TYPE_RGB_ALPHA){
            for(int i = 0; i < hight; i++)
                for(int j = 0; j < with * 4; j += 4){
                    mat[j/4][i].b = row_pointers[i][j+2];
                    mat[j/4][i].g = row_pointers[i][j+1];
                    mat[j/4][i].r = row_pointers[i][j+0];
                }
        }else if(channels == 3 ||
                color_type == PNG_COLOR_TYPE_RGB){
            for(int i = 0; i < hight; i++)
                for(int j = 0; j < with * 3; j += 3){
                    mat[j/3][i].b = row_pointers[i][j+2];
                    mat[j/3][i].g = row_pointers[i][j+1];
                    mat[j/3][i].r = row_pointers[i][j+0];
                }
        }else{
            png_destroy_read_struct(&png_ptr, &info_ptr, 0);
            return false;
        }
        png_destroy_read_struct(&png_ptr, &info_ptr, 0);
        return true;
    }
private:
    unsigned int with;
    unsigned int hight;
    T **mat;
};

#endif /* BMAT_H */


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南波儿万

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值