1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
//! Image file reading and writing, see [OpenCV //! imgcodecs](http://docs.opencv.org/3.1.0/d4/da8/group__imgcodecs.html). use super::core::{CMat, Mat}; use std::ffi::CString; use std::os::raw::{c_char, c_int}; use std::path::Path; // ============================================================================= // Imgproc // ============================================================================= /// ImreadModes #[derive(Debug, PartialEq, Clone, Copy)] pub enum ImreadModes { /// If set, return the loaded image as is (with alpha channel, otherwise it /// gets cropped ImreadUnchanged = -1, /// If set, always convert image to the single channel grayscale image. ImreadGrayscale = 0, /// If set, always convert image to the 3 channel BGR color image. ImreadColor = 1, /// If set, return 16-bit/32-bit image when the input has the corresponding /// depth, otherwise convert it to 8-bit. ImreadAnydepth = 2, /// If set, the image is read in any possible color format. ImreadAnycolor = 4, /// If set, use the gdal driver for loading the image. ImreadLoadGdal = 8, /// If set, always convert image to the single channel grayscale image and /// the image size reduced 1/2. ImreadReducedGrayscale2 = 16, /// If set, always convert image to the 3 channel BGR color image and the /// image size reduced 1/2. ImreadReducedColor2 = 17, /// If set, always convert image to the single channel grayscale image and /// the image size reduced 1/4. ImreadReducedGrayscale4 = 32, /// If set, always convert image to the 3 channel BGR color image and the /// image size reduced 1/4. ImreadReducedColor4 = 33, /// If set, always convert image to the single channel grayscale image and /// the image size reduced 1/8. ImreadReducedGrayscale8 = 64, /// If set, always convert image to the 3 channel BGR color image and the /// image size reduced 1/8. ImreadReducedColor8 = 65, } /// Imwrite flags #[derive(Debug, PartialEq, Clone, Copy)] pub enum ImwriteFlags { /// For JPEG, it can be a quality from 0 to 100 (the higher is the /// better). Default value is 95. ImwriteJpegQuality = 1, /// Enable JPEG features, 0 or 1, default is False. ImwriteJpegProgressive = 2, /// Enable JPEG features, 0 or 1, default is False. ImwriteJpegOptimize = 3, /// JPEG restart interval, 0 - 65535, default is 0 - no restart. ImwriteJpegRstInterval = 4, /// Separate luma quality level, 0 - 100, default is 0 - don't use. ImwriteJpegLumaQuality = 5, /// Separate chroma quality level, 0 - 100, default is 0 - don't use. ImwriteJpegChromaQuality = 6, /// For PNG, it can be the compression level from 0 to 9. A higher value /// means a smaller size and longer compression time. Default value is 3. /// Also strategy is changed to IMWRITE_PNG_STRATEGY_DEFAULT /// (Z_DEFAULT_STRATEGY). ImwritePngCompression = 16, /// One of cv::ImwritePNGFlags, default is IMWRITE_PNG_STRATEGY_DEFAULT. ImwritePngStrategy = 17, /// Binary level PNG, 0 or 1, default is 0. ImwritePngBilevel = 18, /// For PPM, PGM, or PBM, it can be a binary format flag, 0 or 1. Default /// value is 1. ImwritePxmBinary = 32, /// For WEBP, it can be a quality from 1 to 100 (the higher is the /// better). By default (without any parameter) and for quality above 100 /// the lossless compression is used. ImwriteWebpQuality = 64, /// For PAM, sets the TUPLETYPE field to the corresponding string value that /// is defined for the format ImwritePamTupletype = 128, } /// Imwrite PNG flag #[derive(Debug, PartialEq, Clone, Copy)] pub enum ImwritePngFlags { /// Use this value for normal data. ImwritePngStrategyDefault = 0, /// Use this value for data produced by a filter (or predictor).Filtered /// data consists mostly of small values with a somewhat random /// distribution. In this case, the compression algorithm is tuned to /// compress them better. ImwritePngStrategyFiltered = 1, /// Use this value to force Huffman encoding only (no string match). ImwritePngStrategyHuffmanOnly = 2, /// Use this value to limit match distances to one (run-length encoding). ImwritePngStrategyRle = 3, /// Using this value prevents the use of dynamic Huffman codes, allowing for /// a simpler decoder for special applications. ImwritePngStrategyFixed = 4, } extern "C" { fn cv_imread(input: *const c_char, flags: c_int) -> *mut CMat; fn cv_imdecode(buf: *const u8, l: usize, m: c_int) -> *mut CMat; fn cv_imencode(ext: *const c_char, inner: *const CMat, flag_ptr: *const c_int, flag_size: usize) -> ImencodeResult; } #[repr(C)] struct ImencodeResult { status: bool, buf: *mut u8, size: usize, } impl Mat { /// Creates a `Mat` from reading the image specified by the path. pub fn from_path<P: AsRef<Path>>(path: P, flags: ImreadModes) -> Option<Mat> { if let Some(unicode_path) = path.as_ref().as_os_str().to_str() { let s = CString::new(unicode_path).unwrap(); let m = unsafe { cv_imread((&s).as_ptr(), flags as c_int) }; Some(Mat::from_raw(m)) } else { None } } /// Decodes an image from `buf` according to the specified mode. pub fn imdecode(buf: &[u8], mode: ImreadModes) -> Mat { let inner = unsafe { cv_imdecode(buf.as_ptr(), buf.len(), mode as i32) }; Mat::from_raw(inner) } /// Encodes an image; the encoding scheme depends on the extension provided; /// additional write flags can be passed in using a vector. If successful, /// returns an owned vector of the encoded image. pub fn imencode(&self, ext: &str, f: Vec<ImwriteFlags>) -> Option<Vec<u8>> { let ext = CString::new(ext).expect("invalid extension string"); let flags = f.into_iter().map(|f| f as i32).collect::<Vec<_>>(); let r = unsafe { cv_imencode(ext.into_raw(), self.inner, flags.as_ptr(), flags.len()) }; if r.status { unsafe { Some(::std::slice::from_raw_parts(r.buf, r.size).to_vec()) } } else { None } } }