Added imreadmulti API to read multi-paged images into a vector of Mat.

pull/3575/head
Ashod Nakashian 10 years ago
parent ecf359b8c9
commit 61ca38103c
  1. 10
      modules/imgcodecs/include/opencv2/imgcodecs.hpp
  2. 93
      modules/imgcodecs/src/loadsave.cpp

@ -134,6 +134,16 @@ returns an empty matrix ( Mat::data==NULL ). Currently, the following file forma
*/
CV_EXPORTS_W Mat imread( const String& filename, int flags = IMREAD_COLOR );
/** @brief Loads a multi-page image from a file. (see imread for details.)
@param filename Name of file to be loaded.
@param flags Flags specifying the color type of a loaded image (see imread).
Defaults to IMREAD_ANYCOLOR, as each page may be different.
@param mats A vector of Mat objects holding each page, if more than one.
*/
CV_EXPORTS_W bool imreadmulti(const String& filename, std::vector<Mat>& mats, int flags = IMREAD_ANYCOLOR);
/** @brief Saves an image to a specified file.
@param filename Name of the file.

@ -320,6 +320,84 @@ imread_( const String& filename, int flags, int hdrtype, Mat* mat=0 )
hdrtype == LOAD_IMAGE ? (void*)image : (void*)mat;
}
/**
* Read an image into memory and return the information
*
* @param[in] filename File to load
* @param[in] flags Flags
* @param[in] mats Reference to C++ vector<Mat> object to hold the images
*
*/
static bool
imreadmulti_(const String& filename, int flags, std::vector<Mat>& mats)
{
/// Search for the relevant decoder to handle the imagery
ImageDecoder decoder;
#ifdef HAVE_GDAL
if ((flags & IMREAD_LOAD_GDAL) == IMREAD_LOAD_GDAL){
decoder = GdalDecoder().newDecoder();
}
else{
#endif
decoder = findDecoder(filename);
#ifdef HAVE_GDAL
}
#endif
/// if no decoder was found, return nothing.
if (!decoder){
return 0;
}
/// set the filename in the driver
decoder->setSource(filename);
// read the header to make sure it succeeds
if (!decoder->readHeader())
return 0;
for (;;)
{
// grab the decoded type
int type = decoder->type();
if (flags != -1)
{
if ((flags & CV_LOAD_IMAGE_ANYDEPTH) == 0)
type = CV_MAKETYPE(CV_8U, CV_MAT_CN(type));
if ((flags & CV_LOAD_IMAGE_COLOR) != 0 ||
((flags & CV_LOAD_IMAGE_ANYCOLOR) != 0 && CV_MAT_CN(type) > 1))
type = CV_MAKETYPE(CV_MAT_DEPTH(type), 3);
else
type = CV_MAKETYPE(CV_MAT_DEPTH(type), 1);
}
// established the required input image size.
CvSize size;
size.width = decoder->width();
size.height = decoder->height();
Mat mat;
mat.create(size.height, size.width, type);
// read the image data
if (!decoder->readData(mat))
{
break;
}
mats.push_back(mat);
if (!decoder->nextPage())
{
break;
}
}
return !mats.empty();
}
/**
* Read an image
*
@ -340,6 +418,21 @@ Mat imread( const String& filename, int flags )
return img;
}
/**
* Read a multi-page image
*
* This function merely calls the actual implementation above and returns itself.
*
* @param[in] filename File to load
* @param[in] mats Reference to C++ vector<Mat> object to hold the images
* @param[in] flags Flags you wish to set.
*
*/
bool imreadmulti(const String& filename, std::vector<Mat>& mats, int flags)
{
return imreadmulti_(filename, flags, mats);
}
static bool imwrite_( const String& filename, const Mat& image,
const std::vector<int>& params, bool flipv )
{

Loading…
Cancel
Save