diff --git a/modules/imgcodecs/include/opencv2/imgcodecs.hpp b/modules/imgcodecs/include/opencv2/imgcodecs.hpp index c01d8568e49e..acc465593e73 100644 --- a/modules/imgcodecs/include/opencv2/imgcodecs.hpp +++ b/modules/imgcodecs/include/opencv2/imgcodecs.hpp @@ -227,6 +227,17 @@ Currently, the following file formats are supported: */ CV_EXPORTS_W Mat imread( const String& filename, int flags = IMREAD_COLOR ); +/** @brief Loads an image from a file. + +This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts and the return value. +@param filename Name of file to be loaded. +@param dst object in which the image will be loaded. +@param flags Flag that can take values of cv::ImreadModes +@note +The image passing through the img parameter can be pre-allocated. The memory is reused if the shape and the type match with the load image. + */ +CV_EXPORTS_W void imread( const String& filename, OutputArray dst, int flags = IMREAD_COLOR ); + /** @brief Loads a multi-page image from a file. The function imreadmulti loads a multi-page image from the specified file into a vector of Mat objects. diff --git a/modules/imgcodecs/src/loadsave.cpp b/modules/imgcodecs/src/loadsave.cpp index bc28efe49b3b..2586fc1fa4b1 100644 --- a/modules/imgcodecs/src/loadsave.cpp +++ b/modules/imgcodecs/src/loadsave.cpp @@ -457,7 +457,16 @@ imread_( const String& filename, int flags, Mat& mat ) type = CV_MAKETYPE(CV_MAT_DEPTH(type), 1); } - mat.create( size.height, size.width, type ); + if (mat.empty()) + { + mat.create( size.height, size.width, type ); + } + else + { + CV_CheckEQ(size, mat.size(), ""); + CV_CheckTypeEQ(type, mat.type(), ""); + CV_Assert(mat.isContinuous()); + } // read the image data bool success = false; @@ -632,6 +641,16 @@ Mat imread( const String& filename, int flags ) return img; } +void imread( const String& filename, OutputArray dst, int flags ) +{ + CV_TRACE_FUNCTION(); + + Mat img = dst.getMat(); + + /// load the data + imread_(filename, flags, img); +} + /** * Read a multi-page image * diff --git a/modules/imgcodecs/test/test_png.cpp b/modules/imgcodecs/test/test_png.cpp index cdc7da39b282..655c59430d4b 100644 --- a/modules/imgcodecs/test/test_png.cpp +++ b/modules/imgcodecs/test/test_png.cpp @@ -7,6 +7,19 @@ namespace opencv_test { namespace { #if defined(HAVE_PNG) || defined(HAVE_SPNG) +TEST(Imgcodecs_Png, imread_passing_mat) +{ + const string root = cvtest::TS::ptr()->get_data_path(); + const string imgName = root + "../cv/shared/lena.png"; + + Mat ref = imread(imgName); + Mat img(ref.size(), ref.type()); + void* ptr = img.data; + imread(imgName, img); + EXPECT_EQ(cv::norm(ref, img, NORM_INF), 0); + EXPECT_EQ(img.data, ptr); +} + TEST(Imgcodecs_Png, write_big) { const string root = cvtest::TS::ptr()->get_data_path(); diff --git a/modules/python/test/test_imread.py b/modules/python/test/test_imread.py new file mode 100644 index 000000000000..b5f286d42696 --- /dev/null +++ b/modules/python/test/test_imread.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python + +''' +Test for imread +''' + +# Python 2/3 compatibility +from __future__ import print_function + +import cv2 as cv +import numpy as np +import sys + +from tests_common import NewOpenCVTests + +class imread_test(NewOpenCVTests): + def test_imread_to_buffer(self): + path = self.extraTestDataPath + '/cv/shared/lena.png' + ref = cv.imread(path) + + img = np.zeros_like(ref) + cv.imread(path, img) + self.assertEqual(cv.norm(ref, img, cv.NORM_INF), 0.0) + + +if __name__ == '__main__': + NewOpenCVTests.bootstrap() diff --git a/modules/python/test/test_pathlike.py b/modules/python/test/test_pathlike.py index d654ce24adad..9122a757ceea 100644 --- a/modules/python/test/test_pathlike.py +++ b/modules/python/test/test_pathlike.py @@ -28,7 +28,7 @@ def test_pathlib_path(self): def test_type_mismatch(self): import_path() # checks python version - with self.assertRaises(TypeError) as context: + with self.assertRaises(cv.error) as context: cv.imread(123) self.assertTrue('str or path-like' in str(context.exception))