将数据写出成一个灰度png图片

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Blues_lizhen/article/details/83444554

写了一个简单的类,用于将数据直接写出成一个png图片


不多说,且看代码

首先类的定义


pngHandle.h

//
// Created by L on 18-10-26.
//
#ifndef PNG_PNGHANDLE_H
#define PNG_PNGHANDLE_H
#include "png.h"
class pngHandle{
public:
    ~pngHandle();
    pngHandle();
    pngHandle(const int width,const int height);
    void setSize(const int width,const int height);
    bool setBackground(unsigned char value);
    bool setValue(int x,int y,unsigned char value);
    bool write(char * filename);
private:
    bool isSetSize;
    char bit_depth_;//图像深度
    char color_type_;
    int width_; //图寬
    int height_;//图高
    void setBitDepth(char bit_depth);
    void setColortype(char color_type);
    unsigned char *buffer;// 0 <= gray < 255
};
#endif //PNG_PNGHANDLE_H

然后类的实现

pngHandle.cpp

//
// Created by L on 18-10-26.
//
#include <iostream>
#include "pngHandle.h"
pngHandle::~pngHandle(){
    delete[] buffer;
}
pngHandle::pngHandle():
isSetSize(false)
{
    setBitDepth(8);
    setColortype(0);
}
pngHandle::pngHandle(const int width, const int height):
        isSetSize(false)
{
    setBitDepth(8);
    setColortype(0);
    setSize(width, height);
    setBackground(0xff);//默认设置白色
}
void pngHandle::setSize(const int width,const int height){
    width_ = width;
    height_ = height;
    buffer = new unsigned char[width_*height_];
    isSetSize = true;
}
bool pngHandle::setBackground(unsigned char value) {
    if(!isSetSize){
        std::cerr<<"Warning: can't set background, because size wasn't set!"<<std::endl;
        return false;
    }
    for(int i = 0;i < width_*height_;i++){
        buffer[i] = value;
    }
    return true;
}
bool pngHandle::setValue(int x, int y, unsigned char value){
    if(!isSetSize){
        std::cerr<<"Warning: can't set color, because size wasn't set!"<<std::endl;
        return false;
    }
    if((x >= height_) || (y >= width_)) {
        std::cerr<<"Warning: beyond the boundary!"<<std::endl;
        return false;
    }
    buffer[x*width_+y] = value;
    return true;
}
void pngHandle::setBitDepth(char bit_depth) {
    bit_depth_ = bit_depth;
}
void pngHandle::setColortype(char color_type){
    color_type_ = color_type;
}
bool pngHandle::write(char *filename) {
    FILE * fp = fopen(filename,"wb");
    if (!fp) {
        std::cerr << "Warning: could not open png file: " << filename << std::endl;
        return false;
    }
    //创建png_struct
    png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
                                                  (png_voidp)NULL,NULL,NULL);
    if (!png_ptr) {
        fclose(fp);
        std::cerr << "Warning: could not create png_ptr" << std::endl;
        return false;
    }
    //分配内存并初始化图像信息
    png_infop info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
        png_destroy_write_struct(&png_ptr,(png_infopp)NULL);
        std::cerr << "Warning: could not create info_ptr" << std::endl;
        return false;
    }
    //设置输出控制
    png_init_io(png_ptr, fp);
    png_set_IHDR(png_ptr, info_ptr,
                 width_, height_,             // width, height
                 bit_depth_,                  // bits per pixel -- 16 does not work with blockbuster
                 color_type_, // non-alpha options are PNG_COLOR_TYPE_RGB,PNG_COLOR_TYPE_GRAY,
                 PNG_INTERLACE_NONE,
                 PNG_COMPRESSION_TYPE_DEFAULT,
                 PNG_FILTER_TYPE_DEFAULT);
    png_write_info(png_ptr, info_ptr);
    png_byte * row_pointers[height_];
    for (int i = 0; i < height_; ++i)
    {
        row_pointers[i] = (png_byte*)(buffer+i*width_);
    }
    png_write_image(png_ptr, row_pointers);
    png_write_end(png_ptr, NULL);
	 //清空内存
    if (info_ptr != NULL) png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
    if (png_ptr != NULL) png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
    if (row_pointers != NULL) free(row_pointers);
    if (fp != NULL) fclose(fp);
}

最后给一个简单的使用例子

#include "pngHandle.h"
int main() {
    int width = 800;
    int height = 600;
    pngHandle png(width,height);


    for(int x =height/4 ;x<height/2;x++){
        for(int y=0; y<width ; y++)
        {
            png.setValue(x,y,0x00);
        }
    }
    for(int x =0 ;x<height;x++){
        for(int y=width/3; y<width/2 ; y++)
        {
            png.setValue(x,y,205);
        }
    }

    png.write("mypng.png");
    
    return 0;
}

图片如下


mypng.png


先写这么多,现在只有写功能,后续会继续完善其他操作功能,会在我的github上png工程下更新

附工程地址:https://github.com/zhenliysu/png

猜你喜欢

转载自blog.csdn.net/Blues_lizhen/article/details/83444554