Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
D
dlib
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
钟尚武
dlib
Commits
ddac90f4
Commit
ddac90f4
authored
May 27, 2011
by
Davis King
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added a function for saving to the PNG image format.
parent
6f4c65a6
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
285 additions
and
0 deletions
+285
-0
image_io.h
dlib/image_io.h
+1
-0
save_png.h
dlib/image_saver/save_png.h
+239
-0
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