Impl SaveAsPNG
This commit is contained in:
parent
ee63cc2a7c
commit
577e7ae5e9
3 changed files with 86 additions and 1 deletions
75
src/image.cc
75
src/image.cc
|
@ -60,6 +60,80 @@ unsigned int Image::GetHeight() const { return height_; }
|
|||
|
||||
bool Image::IsGrayscale() const { return is_grayscale_; }
|
||||
|
||||
bool Image::SaveAsPNG(const std::string &filename, bool overwrite) {
|
||||
if (!overwrite) {
|
||||
std::ifstream ifs(filename);
|
||||
if (ifs.is_open()) {
|
||||
std::cout << "ERROR: File \"" << filename
|
||||
<< "\" exists but overwrite == false" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
FILE *file = std::fopen(filename.c_str(), "wb");
|
||||
if (!file) {
|
||||
std::cout << "ERROR: Failed to open file \"" << filename
|
||||
<< "\" for writing png" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// init required structs for png encoding
|
||||
png_structp png_ptr =
|
||||
png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
|
||||
if (!png_ptr) {
|
||||
std::cout << "ERROR: Failed to initialize libpng (png_ptr) for encoding "
|
||||
"PNG file \""
|
||||
<< filename << '"' << std::endl;
|
||||
std::fclose(file);
|
||||
return false;
|
||||
}
|
||||
|
||||
png_infop png_info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!png_info_ptr) {
|
||||
std::cout << "ERROR: Failed to initialize libpng (png_infop) for decoding "
|
||||
"PNG file \""
|
||||
<< filename << '"' << std::endl;
|
||||
png_destroy_write_struct(&png_ptr, nullptr);
|
||||
std::fclose(file);
|
||||
return false;
|
||||
}
|
||||
|
||||
// required to handle libpng errors
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
png_destroy_write_struct(&png_ptr, &png_info_ptr);
|
||||
std::fclose(file);
|
||||
return false;
|
||||
}
|
||||
|
||||
// give FILE handle to libpng
|
||||
png_init_io(png_ptr, file);
|
||||
|
||||
// set image information
|
||||
png_set_IHDR(png_ptr, png_info_ptr, width_, height_, 8,
|
||||
PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
|
||||
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
||||
|
||||
// write png info
|
||||
png_write_info(png_ptr, png_info_ptr);
|
||||
|
||||
// write rows of image data
|
||||
for (unsigned int y = 0; y < height_; ++y) {
|
||||
png_write_row(png_ptr, &data_.at(y * width_ * 4));
|
||||
}
|
||||
|
||||
// finish writing image data
|
||||
png_write_end(png_ptr, png_info_ptr);
|
||||
|
||||
// cleanup
|
||||
png_destroy_write_struct(&png_ptr, &png_info_ptr);
|
||||
fclose(file);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Image::SaveAsPNG(const char *filename, bool overwrite) {
|
||||
return SaveAsPNG(std::string(filename), overwrite);
|
||||
}
|
||||
|
||||
bool Image::SaveAsPPM(const std::string &filename, bool overwrite,
|
||||
bool packed) {
|
||||
if (!IsValid()) {
|
||||
|
@ -243,6 +317,7 @@ void Image::DecodePNG(const std::string &filename) {
|
|||
|
||||
// cleanup
|
||||
png_destroy_read_struct(&png_ptr, &png_info_ptr, &png_end_info_ptr);
|
||||
fclose(file);
|
||||
|
||||
// verify
|
||||
if (is_grayscale_) {
|
||||
|
|
10
src/image.h
10
src/image.h
|
@ -58,6 +58,16 @@ class Image {
|
|||
/// Returns true if the image is grayscale. If false, then the image is RGBA.
|
||||
bool IsGrayscale() const;
|
||||
|
||||
/*!
|
||||
* \brief Saves the current image data as a PNG file.
|
||||
*
|
||||
* Returns false if the filename already exists and overwrite is false, or if
|
||||
* saving failed.
|
||||
*/
|
||||
bool SaveAsPNG(const std::string &filename, bool overwrite);
|
||||
/// Same as SaveAsPNG()
|
||||
bool SaveAsPNG(const char *filename, bool overwrite);
|
||||
|
||||
/*!
|
||||
* \brief Saves the current image data as a PPM file.
|
||||
*
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
int main(int argc, char **argv) {
|
||||
Image image("testin.png");
|
||||
|
||||
image.SaveAsPPM("testout.ppm", true, true);
|
||||
image.SaveAsPNG("testout.png", true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue