Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
dlib
Commits
ddac90f4
Commit
ddac90f4
authored
May 27, 2011
by
Davis King
Browse files
Added a function for saving to the PNG image format.
parent
6f4c65a6
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
285 additions
and
0 deletions
+285
-0
dlib/image_io.h
dlib/image_io.h
+1
-0
dlib/image_saver/save_png.h
dlib/image_saver/save_png.h
+239
-0
dlib/image_saver/save_png_abstract.h
dlib/image_saver/save_png_abstract.h
+45
-0
No files found.
dlib/image_io.h
View file @
ddac90f4
...
...
@@ -7,6 +7,7 @@
#include "image_loader/png_loader.h"
#include "image_loader/jpeg_loader.h"
#include "image_saver/image_saver.h"
#include "image_saver/save_png.h"
#endif // DLIB_IMAGe_IO_
dlib/image_saver/save_png.h
0 → 100644
View file @
ddac90f4
// Copyright (C) 2011 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_SAVE_PnG_H__
#define DLIB_SAVE_PnG_H__
#include "save_png_abstract.h"
#include "../image_loader/image_loader.h"
#include "dlib/array2d.h"
#include "dlib/pixel.h"
#include <cstdio>
#include <vector>
#include <string>
#include "../pixel.h"
#ifdef DLIB_PNG_SUPPORT
#include <png.h>
#endif
namespace
dlib
{
#ifdef DLIB_PNG_SUPPORT
// Don't do anything when libpng calls us to tell us about an error. Just return to
// our own code and throw an exception (at the long jump target).
void
png_reader_user_error_fn_silent
(
png_structp
png_struct
,
png_const_charp
)
{
longjmp
(
png_jmpbuf
(
png_struct
),
1
);
}
void
png_reader_user_warning_fn_silent
(
png_structp
,
png_const_charp
)
{
}
#endif
template
<
typename
image_type
>
void
save_png
(
const
image_type
&
img
,
const
std
::
string
&
file_name
)
{
// make sure requires clause is not broken
DLIB_ASSERT
(
img
.
size
()
!=
0
,
"
\t
save_png()"
<<
"
\n\t
You can't save an empty image as a PNG"
);
#ifndef DLIB_PNG_SUPPORT
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
You are getting this error because you are trying to use save_png()
but you haven't defined DLIB_PNG_SUPPORT. You must do so to use
this function. You must also make sure you set your build environment
to link against the libpng library.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
COMPILE_TIME_ASSERT
(
sizeof
(
T
)
==
0
);
#else
std
::
vector
<
png_byte
*>
row_pointers
(
img
.
nr
());
FILE
*
fp
;
png_structp
png_ptr
;
png_infop
info_ptr
;
/* Open the file */
fp
=
fopen
(
file_name
.
c_str
(),
"wb"
);
if
(
fp
==
NULL
)
throw
image_load_error
(
"Unable to open "
+
file_name
+
" for writing."
);
/* Create and initialize the png_struct with the desired error handler
* functions. If you want to use the default stderr and longjump method,
* you can supply NULL for the last three parameters. We also check that
* the library version is compatible with the one used at compile time,
* in case we are using dynamically linked libraries. REQUIRED.
*/
png_ptr
=
png_create_write_struct
(
PNG_LIBPNG_VER_STRING
,
NULL
,
&
png_reader_user_error_fn_silent
,
&
png_reader_user_warning_fn_silent
);
if
(
png_ptr
==
NULL
)
{
fclose
(
fp
);
throw
image_load_error
(
"Error while writing PNG file "
+
file_name
);
}
/* Allocate/initialize the image information data. REQUIRED */
info_ptr
=
png_create_info_struct
(
png_ptr
);
if
(
info_ptr
==
NULL
)
{
fclose
(
fp
);
png_destroy_write_struct
(
&
png_ptr
,
NULL
);
throw
image_load_error
(
"Error while writing PNG file "
+
file_name
);
}
/* Set error handling. REQUIRED if you aren't supplying your own
* error handling functions in the png_create_write_struct() call.
*/
if
(
setjmp
(
png_jmpbuf
(
png_ptr
)))
{
/* If we get here, we had a problem writing the file */
fclose
(
fp
);
png_destroy_write_struct
(
&
png_ptr
,
&
info_ptr
);
throw
image_load_error
(
"Error while writing PNG file "
+
file_name
);
}
/* Set up the output control if you are using standard C streams */
png_init_io
(
png_ptr
,
fp
);
const
int
png_transforms
=
PNG_TRANSFORM_IDENTITY
;
const
long
width
=
img
.
nc
();
const
long
height
=
img
.
nr
();
typedef
typename
image_type
::
type
pixel_type
;
if
(
is_same_type
<
rgb_pixel
,
pixel_type
>::
value
)
{
const
int
bit_depth
=
8
;
int
color_type
=
PNG_COLOR_TYPE_RGB
;
png_set_IHDR
(
png_ptr
,
info_ptr
,
width
,
height
,
bit_depth
,
color_type
,
PNG_INTERLACE_NONE
,
PNG_COMPRESSION_TYPE_DEFAULT
,
PNG_FILTER_TYPE_DEFAULT
);
for
(
unsigned
long
i
=
0
;
i
<
row_pointers
.
size
();
++
i
)
row_pointers
[
i
]
=
(
png_byte
*
)(
&
img
[
i
][
0
]);
png_set_rows
(
png_ptr
,
info_ptr
,
&
row_pointers
[
0
]);
png_write_png
(
png_ptr
,
info_ptr
,
png_transforms
,
NULL
);
}
else
if
(
is_same_type
<
rgb_alpha_pixel
,
pixel_type
>::
value
)
{
const
int
bit_depth
=
8
;
int
color_type
=
PNG_COLOR_TYPE_RGB_ALPHA
;
png_set_IHDR
(
png_ptr
,
info_ptr
,
width
,
height
,
bit_depth
,
color_type
,
PNG_INTERLACE_NONE
,
PNG_COMPRESSION_TYPE_DEFAULT
,
PNG_FILTER_TYPE_DEFAULT
);
for
(
unsigned
long
i
=
0
;
i
<
row_pointers
.
size
();
++
i
)
row_pointers
[
i
]
=
(
png_byte
*
)(
&
img
[
i
][
0
]);
png_set_rows
(
png_ptr
,
info_ptr
,
&
row_pointers
[
0
]);
png_write_png
(
png_ptr
,
info_ptr
,
png_transforms
,
NULL
);
}
else
if
(
pixel_traits
<
pixel_type
>::
hsi
||
pixel_traits
<
pixel_type
>::
rgb
)
{
try
{
// convert from HSI to RGB (Or potentially RGB pixels that aren't laid out as R G B)
array2d
<
rgb_pixel
>::
kernel_1a
temp_img
;
assign_image
(
temp_img
,
img
);
const
int
bit_depth
=
8
;
int
color_type
=
PNG_COLOR_TYPE_RGB
;
png_set_IHDR
(
png_ptr
,
info_ptr
,
width
,
height
,
bit_depth
,
color_type
,
PNG_INTERLACE_NONE
,
PNG_COMPRESSION_TYPE_DEFAULT
,
PNG_FILTER_TYPE_DEFAULT
);
for
(
unsigned
long
i
=
0
;
i
<
row_pointers
.
size
();
++
i
)
row_pointers
[
i
]
=
(
png_byte
*
)(
&
temp_img
[
i
][
0
]);
png_set_rows
(
png_ptr
,
info_ptr
,
&
row_pointers
[
0
]);
png_write_png
(
png_ptr
,
info_ptr
,
png_transforms
,
NULL
);
}
catch
(...)
{
fclose
(
fp
);
png_destroy_write_struct
(
&
png_ptr
,
&
info_ptr
);
throw
;
}
}
else
if
(
pixel_traits
<
pixel_type
>::
rgb_alpha
)
{
try
{
// convert from RGBA pixels that aren't laid out as R G B A
array2d
<
rgb_alpha_pixel
>::
kernel_1a
temp_img
;
assign_image
(
temp_img
,
img
);
const
int
bit_depth
=
8
;
int
color_type
=
PNG_COLOR_TYPE_RGB_ALPHA
;
png_set_IHDR
(
png_ptr
,
info_ptr
,
width
,
height
,
bit_depth
,
color_type
,
PNG_INTERLACE_NONE
,
PNG_COMPRESSION_TYPE_DEFAULT
,
PNG_FILTER_TYPE_DEFAULT
);
for
(
unsigned
long
i
=
0
;
i
<
row_pointers
.
size
();
++
i
)
row_pointers
[
i
]
=
(
png_byte
*
)(
&
temp_img
[
i
][
0
]);
png_set_rows
(
png_ptr
,
info_ptr
,
&
row_pointers
[
0
]);
png_write_png
(
png_ptr
,
info_ptr
,
png_transforms
,
NULL
);
}
catch
(...)
{
fclose
(
fp
);
png_destroy_write_struct
(
&
png_ptr
,
&
info_ptr
);
throw
;
}
}
else
// this is supposed to be grayscale
{
DLIB_CASSERT
(
pixel_traits
<
pixel_type
>::
grayscale
,
"impossible condition detected"
);
if
(
pixel_traits
<
pixel_type
>::
is_unsigned
&&
sizeof
(
pixel_type
)
==
1
)
{
const
int
bit_depth
=
8
;
int
color_type
=
PNG_COLOR_TYPE_GRAY
;
png_set_IHDR
(
png_ptr
,
info_ptr
,
width
,
height
,
bit_depth
,
color_type
,
PNG_INTERLACE_NONE
,
PNG_COMPRESSION_TYPE_DEFAULT
,
PNG_FILTER_TYPE_DEFAULT
);
for
(
unsigned
long
i
=
0
;
i
<
row_pointers
.
size
();
++
i
)
row_pointers
[
i
]
=
(
png_byte
*
)(
&
img
[
i
][
0
]);
png_set_rows
(
png_ptr
,
info_ptr
,
&
row_pointers
[
0
]);
png_write_png
(
png_ptr
,
info_ptr
,
png_transforms
,
NULL
);
}
else
if
(
pixel_traits
<
pixel_type
>::
is_unsigned
&&
sizeof
(
pixel_type
)
==
2
)
{
const
int
bit_depth
=
16
;
int
color_type
=
PNG_COLOR_TYPE_GRAY
;
png_set_IHDR
(
png_ptr
,
info_ptr
,
width
,
height
,
bit_depth
,
color_type
,
PNG_INTERLACE_NONE
,
PNG_COMPRESSION_TYPE_DEFAULT
,
PNG_FILTER_TYPE_DEFAULT
);
for
(
unsigned
long
i
=
0
;
i
<
row_pointers
.
size
();
++
i
)
row_pointers
[
i
]
=
(
png_byte
*
)(
&
img
[
i
][
0
]);
png_set_rows
(
png_ptr
,
info_ptr
,
&
row_pointers
[
0
]);
png_write_png
(
png_ptr
,
info_ptr
,
png_transforms
,
NULL
);
}
else
{
try
{
// convert from whatever this is to 16bit grayscale
array2d
<
dlib
::
uint16
>::
kernel_1a
temp_img
;
assign_image
(
temp_img
,
img
);
const
int
bit_depth
=
16
;
int
color_type
=
PNG_COLOR_TYPE_GRAY
;
png_set_IHDR
(
png_ptr
,
info_ptr
,
width
,
height
,
bit_depth
,
color_type
,
PNG_INTERLACE_NONE
,
PNG_COMPRESSION_TYPE_DEFAULT
,
PNG_FILTER_TYPE_DEFAULT
);
for
(
unsigned
long
i
=
0
;
i
<
row_pointers
.
size
();
++
i
)
row_pointers
[
i
]
=
(
png_byte
*
)(
&
temp_img
[
i
][
0
]);
png_set_rows
(
png_ptr
,
info_ptr
,
&
row_pointers
[
0
]);
png_write_png
(
png_ptr
,
info_ptr
,
png_transforms
,
NULL
);
}
catch
(...)
{
fclose
(
fp
);
png_destroy_write_struct
(
&
png_ptr
,
&
info_ptr
);
throw
;
}
}
}
/* Clean up after the write, and free any memory allocated */
png_destroy_write_struct
(
&
png_ptr
,
&
info_ptr
);
/* Close the file */
fclose
(
fp
);
#endif
}
}
#endif // DLIB_SAVE_PnG_H__
dlib/image_saver/save_png_abstract.h
0 → 100644
View file @
ddac90f4
// Copyright (C) 2011 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#undef DLIB_SAVE_PnG_ABSTRACT_
#ifdef DLIB_SAVE_PnG_ABSTRACT_
#include "../pixel.h"
namespace
dlib
{
// ----------------------------------------------------------------------------------------
template
<
typename
image_type
>
void
save_png
(
const
image_type
&
image
,
const
std
::
string
&
file_name
);
/*!
requires
- image_type == is an implementation of array2d/array2d_kernel_abstract.h
- pixel_traits<typename image_type::type> is defined
- image.size() != 0
ensures
- writes the image to the file indicated by file_name in the PNG (Portable Network Graphics)
format.
- image[0][0] will be in the upper left corner of the image.
- image[image.nr()-1][image.nc()-1] will be in the lower right
corner of the image.
throws
- image_save_error
This exception is thrown if there is an error that prevents us from saving
the image.
- std::bad_alloc
!*/
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_SAVE_PnG_ABSTRACT_
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment