Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/imageio-2.35.1-py3.8.egg/imageio/plugins/rawpy.py: 2%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

83 statements  

1""" Read/Write images using rawpy. 

2 

3rawpy is an easy-to-use Python wrapper for the LibRaw library. 

4It also contains some extra functionality for finding and repairing hot/dead pixels. 

5""" 

6 

7from typing import Any, Dict, Iterator, List, Optional, Tuple, Union 

8import rawpy 

9import numpy as np 

10 

11from ..core.request import URI_BYTES, InitializationError, IOMode, Request 

12from ..core.v3_plugin_api import ImageProperties, PluginV3 

13from ..typing import ArrayLike 

14 

15 

16class RawPyPlugin(PluginV3): 

17 """A class representing the rawpy plugin. 

18 

19 Methods 

20 ------- 

21 

22 .. autosummary:: 

23 :toctree: _plugins/rawpy 

24 

25 RawPyPlugin.read 

26 """ 

27 

28 def __init__(self, request: Request) -> None: 

29 """Instantiates a new rawpy plugin object 

30 

31 Parameters 

32 ---------- 

33 request: Request 

34 A request object representing the resource to be operated on. 

35 """ 

36 

37 super().__init__(request) 

38 

39 self._image_file = None 

40 

41 if request.mode.io_mode == IOMode.read: 

42 try: 

43 self._image_file = rawpy.imread(request.get_file()) 

44 except ( 

45 rawpy.NotSupportedError, 

46 rawpy.LibRawFileUnsupportedError, 

47 rawpy.LibRawIOError, 

48 ): 

49 if request._uri_type == URI_BYTES: 

50 raise InitializationError( 

51 "RawPy can not read the provided bytes." 

52 ) from None 

53 else: 

54 raise InitializationError( 

55 f"RawPy can not read {request.raw_uri}." 

56 ) from None 

57 elif request.mode.io_mode == IOMode.write: 

58 raise InitializationError("RawPy does not support writing.") from None 

59 

60 def close(self) -> None: 

61 if self._image_file: 

62 self._image_file.close() 

63 

64 self._request.finish() 

65 

66 def read(self, *, index: int = 0, **kwargs) -> np.ndarray: 

67 """Read Raw Image. 

68 

69 Returns 

70 ------- 

71 nd_image: ndarray 

72 The image data 

73 """ 

74 

75 nd_image: np.ndarray 

76 

77 try: 

78 nd_image = self._image_file.postprocess(**kwargs) 

79 except Exception: 

80 pass 

81 

82 if index is Ellipsis: 

83 nd_image = nd_image[None, ...] 

84 

85 return nd_image 

86 

87 def write(self, ndimage: Union[ArrayLike, List[ArrayLike]]) -> Optional[bytes]: 

88 """RawPy does not support writing.""" 

89 raise NotImplementedError() 

90 

91 def iter(self) -> Iterator[np.ndarray]: 

92 """Load the image. 

93 

94 Returns 

95 ------- 

96 nd_image: ndarray 

97 The image data 

98 """ 

99 

100 try: 

101 yield self.read() 

102 except Exception: 

103 pass 

104 

105 def metadata( 

106 self, index: int = None, exclude_applied: bool = True 

107 ) -> Dict[str, Any]: 

108 """Read ndimage metadata. 

109 

110 Parameters 

111 ---------- 

112 exclude_applied : bool 

113 If True, exclude metadata fields that are applied to the image while 

114 reading. For example, if the binary data contains a rotation flag, 

115 the image is rotated by default and the rotation flag is excluded 

116 from the metadata to avoid confusion. 

117 

118 Returns 

119 ------- 

120 metadata : dict 

121 A dictionary of format-specific metadata. 

122 

123 """ 

124 

125 metadata = {} 

126 

127 image_size = self._image_file.sizes 

128 

129 metadata["black_level_per_channel"] = self._image_file.black_level_per_channel 

130 metadata["camera_white_level_per_channel"] = ( 

131 self._image_file.camera_white_level_per_channel 

132 ) 

133 metadata["color_desc"] = self._image_file.color_desc 

134 metadata["color_matrix"] = self._image_file.color_matrix 

135 metadata["daylight_whitebalance"] = self._image_file.daylight_whitebalance 

136 metadata["dtype"] = self._image_file.raw_image.dtype 

137 metadata["flip"] = image_size.flip 

138 metadata["num_colors"] = self._image_file.num_colors 

139 metadata["tone_curve"] = self._image_file.tone_curve 

140 metadata["width"] = image_size.width 

141 metadata["height"] = image_size.height 

142 metadata["raw_width"] = image_size.raw_width 

143 metadata["raw_height"] = image_size.raw_height 

144 metadata["raw_shape"] = self._image_file.raw_image.shape 

145 metadata["iwidth"] = image_size.iwidth 

146 metadata["iheight"] = image_size.iheight 

147 metadata["pixel_aspect"] = image_size.pixel_aspect 

148 metadata["white_level"] = self._image_file.white_level 

149 

150 if exclude_applied: 

151 metadata.pop("black_level_per_channel", None) 

152 metadata.pop("camera_white_level_per_channel", None) 

153 metadata.pop("color_desc", None) 

154 metadata.pop("color_matrix", None) 

155 metadata.pop("daylight_whitebalance", None) 

156 metadata.pop("dtype", None) 

157 metadata.pop("flip", None) 

158 metadata.pop("num_colors", None) 

159 metadata.pop("tone_curve", None) 

160 metadata.pop("raw_width", None) 

161 metadata.pop("raw_height", None) 

162 metadata.pop("raw_shape", None) 

163 metadata.pop("iwidth", None) 

164 metadata.pop("iheight", None) 

165 metadata.pop("white_level", None) 

166 

167 return metadata 

168 

169 def properties(self, index: int = None) -> ImageProperties: 

170 """Standardized ndimage metadata 

171 

172 Returns 

173 ------- 

174 properties : ImageProperties 

175 A dataclass filled with standardized image metadata. 

176 

177 Notes 

178 ----- 

179 This does not decode pixel data and is fast for large images. 

180 

181 """ 

182 

183 ImageSize = self._image_file.sizes 

184 

185 width: int = ImageSize.width 

186 height: int = ImageSize.height 

187 shape: Tuple[int, ...] = (height, width) 

188 

189 dtype = self._image_file.raw_image.dtype 

190 

191 return ImageProperties(shape=shape, dtype=dtype)