From: Ashod Nakashian Date: Mon, 29 Dec 2014 15:50:42 +0000 (-0500) Subject: Added imreadmulti API to read multi-paged images into a vector of Mat. X-Git-Tag: accepted/tizen/6.0/unified/20201030.111113~2749^2~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=61ca38103c690580e7eb1d1a670c592a792673e0;p=platform%2Fupstream%2Fopencv.git Added imreadmulti API to read multi-paged images into a vector of Mat. --- diff --git a/modules/imgcodecs/include/opencv2/imgcodecs.hpp b/modules/imgcodecs/include/opencv2/imgcodecs.hpp index f8c6900..a22d3dc 100644 --- a/modules/imgcodecs/include/opencv2/imgcodecs.hpp +++ b/modules/imgcodecs/include/opencv2/imgcodecs.hpp @@ -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& mats, int flags = IMREAD_ANYCOLOR); + /** @brief Saves an image to a specified file. @param filename Name of the file. diff --git a/modules/imgcodecs/src/loadsave.cpp b/modules/imgcodecs/src/loadsave.cpp index 7359871..c06b42a 100644 --- a/modules/imgcodecs/src/loadsave.cpp +++ b/modules/imgcodecs/src/loadsave.cpp @@ -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 object to hold the images +* +*/ +static bool +imreadmulti_(const String& filename, int flags, std::vector& 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 object to hold the images +* @param[in] flags Flags you wish to set. +* +*/ +bool imreadmulti(const String& filename, std::vector& mats, int flags) +{ + return imreadmulti_(filename, flags, mats); +} + static bool imwrite_( const String& filename, const Mat& image, const std::vector& params, bool flipv ) {