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::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 Image::SaveAsPPM(const std::string &filename, bool overwrite,
|
||||||
bool packed) {
|
bool packed) {
|
||||||
if (!IsValid()) {
|
if (!IsValid()) {
|
||||||
|
@ -243,6 +317,7 @@ void Image::DecodePNG(const std::string &filename) {
|
||||||
|
|
||||||
// cleanup
|
// cleanup
|
||||||
png_destroy_read_struct(&png_ptr, &png_info_ptr, &png_end_info_ptr);
|
png_destroy_read_struct(&png_ptr, &png_info_ptr, &png_end_info_ptr);
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
if (is_grayscale_) {
|
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.
|
/// Returns true if the image is grayscale. If false, then the image is RGBA.
|
||||||
bool IsGrayscale() const;
|
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.
|
* \brief Saves the current image data as a PPM file.
|
||||||
*
|
*
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
Image image("testin.png");
|
Image image("testin.png");
|
||||||
|
|
||||||
image.SaveAsPPM("testout.ppm", true, true);
|
image.SaveAsPNG("testout.png", true);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue