图像处理-图片读写

来源:互联网 发布:2016淘宝排名新规则 编辑:程序博客网 时间:2024/05/21 17:54

图片读写

stb

在matlab中利用imread和imwrite来对图片进行读写,在c++中推荐一个很好用的库–stb,这个库只需要一个头文件,就可以对多种类型的图片进行解析和保存,并且使用方便,接口数很少。在github上下载stb_image和stb_image_write这两个文件,其中stb_image用于图片的解析,stb_image_write用于图片的保存。
注意一点,在使用stb_image和stb_image_write之前,需要进行宏定义,具体请参看这个文件的文件注释。

示例

接下来用代码说明stb的使用方法。具体代码参看这里,所有头文件在Include文件夹,对应的cpp在lib文件夹中。

Image.h图片抽象类

#pragma once#include <assert.h>#include <cstring>class Image{protected:    unsigned int m_width;    unsigned int m_height;    unsigned int m_components;public:    Image(int w, int h, int n);    virtual ~Image() = default;    //getter and setter    unsigned int GetWidth()const { return m_width; }    unsigned int GetHeight()const { return m_height; }    unsigned int GetComponents()const { return m_components; }    unsigned int GetSize()const { return m_width*m_height*m_components; }};

Image.cpp

#include "Image.h"#include <iostream>Image::Image(int w, int h, int n):    m_width(w), m_height(h), m_components(n){}

UnsignedImage.h 无符号整型图片

#pragma once#include "Image.h"#include <vector>class UnsignedImage : public Image{private:    std::vector<unsigned char> m_data;public:    UnsignedImage(int w, int h, int n, const unsigned char* data);    ~UnsignedImage()=default;    std::vector<unsigned char> GetData()const { return m_data; }    const unsigned char& At(int row, int col, int nth)const;    unsigned char&At(int row, int col, int nth);};

UnsignedImage.cpp 注意这里的At函数,stb将图片解析为一维数组,为了更直观对图片像素进行操作,At函数提供了一个指定行列和通道的接口。

#include "UnsignedImage.h"UnsignedImage::UnsignedImage(int w, int h, int n, const unsigned char* data):    Image(w, h, n){    m_data.resize(this->GetSize());    memcpy(&m_data[0], data, sizeof(unsigned char) * this->GetSize());}const unsigned char & UnsignedImage::At(int row, int col, int nth)const{    assert(row <= m_height && col <= m_width && nth <= m_components);    return m_data[row*m_width*m_components + col*m_components + nth];}unsigned char& UnsignedImage::At(int row, int col, int nth){    assert(row <= m_height && col <= m_width && nth <= m_components);    return m_data[row*m_width*m_components + col*m_components + nth];}

ImageLWManager.h 用于图片的加载(Loading)和写入(Write),stb支持多种类型图片的读写,这里只写了一个png格式的写入。

#pragma once#include "Image.h"#include "UnsignedImage.h"#include "common/common.h"#include <cstring>class ImageLoader{    DISALLOW_COPY_AND_ASSIGN(ImageLoader);public:    ImageLoader() = default;    UnsignedImage LoadImage(const std::string& filePath, int req_comp=0);};class ImageWriter{    DISALLOW_COPY_AND_ASSIGN(ImageWriter);public:    ImageWriter() = default;    int WritePNGImage(const UnsignedImage& image, const std::string& outputPath)const;};

ImageLWManager.cpp 注意在使用stb之前需要宏定义。

#include "ImageLWManager.h"#include <iostream>#define STB_IMAGE_IMPLEMENTATION#include "stb/stb_image.h"#define STB_IMAGE_WRITE_IMPLEMENTATION#include "stb/stb_image_write.h"UnsignedImage ImageLoader::LoadImage(const std::string& filePath, int req_comp /*= 0*/){    int x, y, n;    auto data = stbi_load(filePath.c_str(), &x, &y, &n, req_comp);    if (req_comp != 0 && n > req_comp)        n = req_comp;    if (nullptr == data)    {        std::cerr << "Can't open the file.\n";        exit(-1);    }    UnsignedImage image(x, y, n, data);    return image;}int ImageWriter::WritePNGImage(const UnsignedImage& image, const std::string& outputPath)const{    return stbi_write_png(outputPath.c_str(),        image.GetWidth(),        image.GetHeight(),        image.GetComponents(),        &(image.GetData()[0]),        0);}
0 0