list(APPEND grfmt_srcs ${CMAKE_CURRENT_LIST_DIR}/src/bitstrm.cpp)
list(APPEND grfmt_hdrs ${CMAKE_CURRENT_LIST_DIR}/src/rgbe.hpp)
list(APPEND grfmt_srcs ${CMAKE_CURRENT_LIST_DIR}/src/rgbe.cpp)
-list(APPEND grfmt_hdrs ${CMAKE_CURRENT_LIST_DIR}/src/jpeg_exif.hpp)
-list(APPEND grfmt_srcs ${CMAKE_CURRENT_LIST_DIR}/src/jpeg_exif.cpp)
+list(APPEND grfmt_hdrs ${CMAKE_CURRENT_LIST_DIR}/src/exif.hpp)
+list(APPEND grfmt_srcs ${CMAKE_CURRENT_LIST_DIR}/src/exif.cpp)
source_group("Src\\grfmts" FILES ${grfmt_hdrs} ${grfmt_srcs})
IMREAD_REDUCED_GRAYSCALE_4 = 32, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/4.
IMREAD_REDUCED_COLOR_4 = 33, //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/4.
IMREAD_REDUCED_GRAYSCALE_8 = 64, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/8.
- IMREAD_REDUCED_COLOR_8 = 65 //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/8.
+ IMREAD_REDUCED_COLOR_8 = 65, //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/8.
+ IMREAD_IGNORE_ORIENTATION = 128 //!< If set, do not rotate the image according to EXIF's orientation flag.
};
//! Imwrite flags
/* any depth, ? */
CV_LOAD_IMAGE_ANYDEPTH =2,
/* ?, any color */
- CV_LOAD_IMAGE_ANYCOLOR =4
+ CV_LOAD_IMAGE_ANYCOLOR =4,
+/* ?, no rotate */
+ CV_LOAD_IMAGE_IGNORE_ORIENTATION =128
};
/* load image from file
//
//M*/
-#include "jpeg_exif.hpp"
+#include "exif.hpp"
namespace {
}
/**
- * @brief Parsing the jpeg file and prepare (internally) exif directory structure
+ * @brief Parsing the file and prepare (internally) exif directory structure
* @return true if parsing was successful and exif information exists in JpegReader object
* false in case of unsuccessful parsing
*/
/**
- * @brief Get exif directory structure contained in jpeg file (if any)
+ * @brief Get exif directory structure contained in file (if any)
* This is internal function and is not exposed to client
*
* @return Map where key is tag number and value is ExifEntry_t structure
//M*/
-#ifndef _OPENCV_JPEG_EXIF_HPP_
-#define _OPENCV_JPEG_EXIF_HPP_
+#ifndef _OPENCV_EXIF_HPP_
+#define _OPENCV_EXIF_HPP_
#include <cstdio>
#include <map>
};
/**
- * @brief Picture orientation which may be taken from JPEG's EXIF
+ * @brief Picture orientation which may be taken from EXIF
* Orientation usually matters when the picture is taken by
* smartphone or other camera with orientation sensor support
* Corresponds to EXIF 2.3 Specification
*/
-enum JpegOrientation
+enum ImageOrientation
{
- JPEG_ORIENTATION_TL = 1, ///< 0th row == visual top, 0th column == visual left-hand side
- JPEG_ORIENTATION_TR = 2, ///< 0th row == visual top, 0th column == visual right-hand side
- JPEG_ORIENTATION_BR = 3, ///< 0th row == visual bottom, 0th column == visual right-hand side
- JPEG_ORIENTATION_BL = 4, ///< 0th row == visual bottom, 0th column == visual left-hand side
- JPEG_ORIENTATION_LT = 5, ///< 0th row == visual left-hand side, 0th column == visual top
- JPEG_ORIENTATION_RT = 6, ///< 0th row == visual right-hand side, 0th column == visual top
- JPEG_ORIENTATION_RB = 7, ///< 0th row == visual right-hand side, 0th column == visual bottom
- JPEG_ORIENTATION_LB = 8 ///< 0th row == visual left-hand side, 0th column == visual bottom
+ IMAGE_ORIENTATION_TL = 1, ///< Horizontal (normal)
+ IMAGE_ORIENTATION_TR = 2, ///< Mirrored horizontal
+ IMAGE_ORIENTATION_BR = 3, ///< Rotate 180
+ IMAGE_ORIENTATION_BL = 4, ///< Mirrored vertical
+ IMAGE_ORIENTATION_LT = 5, ///< Mirrored horizontal & rotate 270 CW
+ IMAGE_ORIENTATION_RT = 6, ///< Rotate 90 CW
+ IMAGE_ORIENTATION_RB = 7, ///< Mirrored horizontal & rotate 90 CW
+ IMAGE_ORIENTATION_LB = 8 ///< Rotate 270 CW
};
/**
}
-#endif /* JPEG_EXIF_HPP_ */
+#endif /* _OPENCV_EXIF_HPP_ */
#include "precomp.hpp"
#include "grfmt_jpeg.hpp"
-#include "jpeg_exif.hpp"
#ifdef HAVE_JPEG
m_state = 0;
m_f = 0;
m_buf_supported = true;
- m_orientation = JPEG_ORIENTATION_TL;
}
}
}
- m_orientation = getOrientation();
-
if( !result )
close();
return result;
}
-int JpegDecoder::getOrientation()
-{
- int orientation = JPEG_ORIENTATION_TL;
-
- if (m_filename.size() > 0)
- {
- ExifReader reader( m_filename );
- if( reader.parse() )
- {
- ExifEntry_t entry = reader.getTag( ORIENTATION );
- if (entry.tag != INVALID_TAG)
- {
- orientation = entry.field_u16; //orientation is unsigned short, so check field_u16
- }
- }
- }
-
- return orientation;
-}
-
-void JpegDecoder::setOrientation(Mat& img)
-{
- switch( m_orientation )
- {
- case JPEG_ORIENTATION_TL: //0th row == visual top, 0th column == visual left-hand side
- //do nothing, the image already has proper orientation
- break;
- case JPEG_ORIENTATION_TR: //0th row == visual top, 0th column == visual right-hand side
- flip(img, img, 1); //flip horizontally
- break;
- case JPEG_ORIENTATION_BR: //0th row == visual bottom, 0th column == visual right-hand side
- flip(img, img, -1);//flip both horizontally and vertically
- break;
- case JPEG_ORIENTATION_BL: //0th row == visual bottom, 0th column == visual left-hand side
- flip(img, img, 0); //flip vertically
- break;
- case JPEG_ORIENTATION_LT: //0th row == visual left-hand side, 0th column == visual top
- transpose(img, img);
- break;
- case JPEG_ORIENTATION_RT: //0th row == visual right-hand side, 0th column == visual top
- transpose(img, img);
- flip(img, img, 1); //flip horizontally
- break;
- case JPEG_ORIENTATION_RB: //0th row == visual right-hand side, 0th column == visual bottom
- transpose(img, img);
- flip(img, img, -1); //flip both horizontally and vertically
- break;
- case JPEG_ORIENTATION_LB: //0th row == visual left-hand side, 0th column == visual bottom
- transpose(img, img);
- flip(img, img, 0); //flip vertically
- break;
- default:
- //by default the image read has normal (JPEG_ORIENTATION_TL) orientation
- break;
- }
-}
-
/***************************************************************************
* following code is for supporting MJPEG image files
* based on a message of Laurent Pinchart on the video4linux mailing list
result = true;
jpeg_finish_decompress( cinfo );
- setOrientation( img );
}
}
FILE* m_f;
void* m_state;
-
-private:
- //Support for handling exif orientation tag in Jpeg file
- int m_orientation;
- int getOrientation();
- void setOrientation(Mat& img);
};
#include "precomp.hpp"
#include "grfmts.hpp"
+#include "utils.hpp"
+#include "exif.hpp"
#undef min
#undef max
#include <iostream>
return ImageEncoder();
}
+
enum { LOAD_CVMAT=0, LOAD_IMAGE=1, LOAD_MAT=2 };
+void RotateImage(const String& filename, Mat& img);
+
/**
* Read an image into memory and return the information
*
Mat mat(decoder->height(), decoder->width(), type);
if (!decoder->readData(mat))
{
+ // optionally rotate the data if EXIF' orientation flag says so
+ if( (flags & IMREAD_IGNORE_ORIENTATION) == 0 )
+ {
+ RotateImage(filename, mat);
+ }
+
break;
}
return !mats.empty();
}
+void RotateImage(const String& filename, Mat& img)
+{
+ int orientation = IMAGE_ORIENTATION_TL;
+
+ if (filename.size() > 0)
+ {
+ ExifReader reader( filename );
+ if( reader.parse() )
+ {
+ ExifEntry_t entry = reader.getTag( ORIENTATION );
+ if (entry.tag != INVALID_TAG)
+ {
+ orientation = entry.field_u16; //orientation is unsigned short, so check field_u16
+ }
+ }
+ }
+
+ switch( orientation )
+ {
+ case IMAGE_ORIENTATION_TL: //0th row == visual top, 0th column == visual left-hand side
+ //do nothing, the image already has proper orientation
+ break;
+ case IMAGE_ORIENTATION_TR: //0th row == visual top, 0th column == visual right-hand side
+ flip(img, img, 1); //flip horizontally
+ break;
+ case IMAGE_ORIENTATION_BR: //0th row == visual bottom, 0th column == visual right-hand side
+ flip(img, img, -1);//flip both horizontally and vertically
+ break;
+ case IMAGE_ORIENTATION_BL: //0th row == visual bottom, 0th column == visual left-hand side
+ flip(img, img, 0); //flip vertically
+ break;
+ case IMAGE_ORIENTATION_LT: //0th row == visual left-hand side, 0th column == visual top
+ transpose(img, img);
+ break;
+ case IMAGE_ORIENTATION_RT: //0th row == visual right-hand side, 0th column == visual top
+ transpose(img, img);
+ flip(img, img, 1); //flip horizontally
+ break;
+ case IMAGE_ORIENTATION_RB: //0th row == visual right-hand side, 0th column == visual bottom
+ transpose(img, img);
+ flip(img, img, -1); //flip both horizontally and vertically
+ break;
+ case IMAGE_ORIENTATION_LB: //0th row == visual left-hand side, 0th column == visual bottom
+ transpose(img, img);
+ flip(img, img, 0); //flip vertically
+ break;
+ default:
+ //by default the image read has normal (JPEG_ORIENTATION_TL) orientation
+ break;
+ }
+}
+
+
/**
* Read an image
*
/// load the data
imread_( filename, flags, LOAD_MAT, &img );
+ /// optionally rotate the data if EXIF' orientation flag says so
+ if( (flags & IMREAD_IGNORE_ORIENTATION) == 0 )
+ {
+ RotateImage(filename, img);
+ }
+
/// return a reference to the data
return img;
}