@@ -4,10 +4,11 @@ use clap::Parser;
44use dialoguer:: FuzzySelect ;
55use dialoguer:: theme:: ColorfulTheme ;
66use image:: codecs:: png:: PngEncoder ;
7- use image:: { GenericImageView , ImageEncoder , ImageError } ;
7+ use image:: { GenericImageView , ImageEncoder , ImageError , Rgba } ;
88pub use libharuhishot:: HaruhiShotState ;
9+ use libharuhishot:: reexport:: Transform ;
910use libharuhishot:: {
10- CaptureOption , ClipImageViewInfo , ClipRegion , ImageInfo , Position , Region , Size ,
11+ CaptureOption , ClipImageViewInfoArea , ClipRegion , ImageInfo , Position , Region , Size ,
1112} ;
1213
1314use std:: io:: { BufWriter , Write , stdout} ;
@@ -148,9 +149,9 @@ fn capture_area(
148149 let mut min_y = i32:: MAX ;
149150 let mut max_x = i32:: MIN ;
150151 let mut max_y = i32:: MIN ;
151- for view in & views {
152- let Position { x, y } = view. region . absolute_position_real ( ) ;
153- let Size { width, height } = view. region . clip_size_real ( ) ;
152+ for view in & views. areas {
153+ let Position { x, y } = view. region . display_position_real ( ) ;
154+ let Size { width, height } = view. region . display_logical_size ( ) ;
154155
155156 min_x = min_x. min ( x) ;
156157 min_y = min_y. min ( y) ;
@@ -161,16 +162,17 @@ fn capture_area(
161162 let total_height = ( max_y - min_y) as u32 ;
162163
163164 let mut combined_image = image:: RgbaImage :: new ( total_width, total_height) ;
164- for ClipImageViewInfo {
165+ for ClipImageViewInfoArea {
165166 info :
166167 ImageInfo {
167168 data,
168169 width : img_width,
169170 height : img_height,
171+ transform,
170172 ..
171173 } ,
172174 region,
173- } in views
175+ } in views. areas
174176 {
175177 // Load the captured image
176178 let img = image:: ImageBuffer :: from_raw ( img_width, img_height, data) . ok_or (
@@ -181,43 +183,66 @@ fn capture_area(
181183 ) ) ,
182184 ) ?;
183185
184- // we use the relative position to make image
185- let Position { x, y } = region. relative_position_wl ( ) ;
186-
187- let Size { width, height } = region. clip_size_real ( ) ;
188-
189- let subimage = img
190- . view ( x as u32 , y as u32 , width as u32 , height as u32 )
191- . to_image ( ) ;
192- let rgba_img: image:: RgbaImage = subimage;
193-
186+ let img = match transform {
187+ Transform :: Normal => img,
188+ Transform :: _90 => image:: imageops:: rotate90 ( & img) ,
189+ Transform :: _180 => image:: imageops:: rotate180 ( & img) ,
190+ Transform :: _270 => image:: imageops:: rotate270 ( & img) ,
191+ Transform :: Flipped => image:: imageops:: flip_vertical ( & img) ,
192+ Transform :: Flipped90 => {
193+ image:: imageops:: flip_vertical ( & image:: imageops:: rotate90 ( & img) )
194+ }
195+ Transform :: Flipped180 => {
196+ image:: imageops:: flip_vertical ( & image:: imageops:: rotate180 ( & img) )
197+ }
198+ Transform :: Flipped270 => {
199+ image:: imageops:: flip_vertical ( & image:: imageops:: rotate270 ( & img) )
200+ }
201+ _ => unreachable ! ( ) ,
202+ } ;
203+ let Size { width, height } = region. display_logical_size ( ) ;
204+ let img = image:: imageops:: resize (
205+ & img,
206+ width as u32 ,
207+ height as u32 ,
208+ image:: imageops:: FilterType :: Gaussian ,
209+ ) ;
194210 // we use the real position to calculate the position
195- let Position { x, y } = region. absolute_position_real ( ) ;
211+ let Position { x, y } = region. display_position_real ( ) ;
196212 // Calculate the position in he combined image
197213 let offset_x = ( x - min_x) as u32 ;
198214 let offset_y = ( y - min_y) as u32 ;
199215
200216 // Copy the output image to the combined image
201- for ( x, y, pixel) in rgba_img . enumerate_pixels ( ) {
217+ for ( x, y, pixel) in img . enumerate_pixels ( ) {
202218 let target_x = offset_x + x;
203219 let target_y = offset_y + y;
204220 if target_x < total_width && target_y < total_height {
205221 combined_image. put_pixel ( target_x, target_y, * pixel) ;
206222 }
207223 }
208224 }
225+ let clip_region = views. region ;
226+ let image = combined_image
227+ . view (
228+ clip_region. position . x as u32 ,
229+ clip_region. position . y as u32 ,
230+ clip_region. size . width as u32 ,
231+ clip_region. size . height as u32 ,
232+ )
233+ . to_image ( ) ;
209234
210235 if use_stdout {
211236 let mut buff = std:: io:: Cursor :: new ( Vec :: new ( ) ) ;
212- combined_image . write_to ( & mut buff, image:: ImageFormat :: Png ) ?;
237+ image . write_to ( & mut buff, image:: ImageFormat :: Png ) ?;
213238 let content = buff. get_ref ( ) ;
214239 let stdout = stdout ( ) ;
215240 let mut writer = BufWriter :: new ( stdout. lock ( ) ) ;
216241 writer. write_all ( content) ?;
217242 Ok ( HaruhiShotResult :: StdoutSucceeded )
218243 } else {
219244 let file = random_file_path ( ) ;
220- combined_image . save ( & file) ?;
245+ image . save ( & file) ?;
221246 Ok ( HaruhiShotResult :: SaveToFile ( file) )
222247 }
223248}
@@ -233,13 +258,14 @@ fn get_color(state: &mut HaruhiShotState) -> Result<HaruhiShotResult, HaruhiImag
233258 ) ) ?;
234259 waysip_to_region ( info. size ( ) , info. left_top_point ( ) )
235260 } ) ?;
236- let ClipImageViewInfo {
261+ let ClipImageViewInfoArea {
237262 info :
238263 ImageInfo {
239264 data,
240265 width : img_width,
241266 height : img_height,
242- color_type,
267+ transform,
268+ ..
243269 } ,
244270 region :
245271 ClipRegion {
@@ -250,11 +276,24 @@ fn get_color(state: &mut HaruhiShotState) -> Result<HaruhiShotResult, HaruhiImag
250276 } ,
251277 ..
252278 } ,
253- } = views. remove ( 0 ) ;
254-
255- let mut buff = std:: io:: Cursor :: new ( Vec :: new ( ) ) ;
256- PngEncoder :: new ( & mut buff) . write_image ( & data, img_width, img_height, color_type. into ( ) ) ?;
257- let img = image:: load_from_memory_with_format ( buff. get_ref ( ) , image:: ImageFormat :: Png ) . unwrap ( ) ;
279+ } = views. areas . remove ( 0 ) ;
280+ let image: image:: ImageBuffer < Rgba < u8 > , Vec < u8 > > =
281+ image:: ImageBuffer :: from_raw ( img_width, img_height, data) . unwrap ( ) ;
282+ let img = match transform {
283+ Transform :: Normal => image,
284+ Transform :: _90 => image:: imageops:: rotate90 ( & image) ,
285+ Transform :: _180 => image:: imageops:: rotate180 ( & image) ,
286+ Transform :: _270 => image:: imageops:: rotate270 ( & image) ,
287+ Transform :: Flipped => image:: imageops:: flip_vertical ( & image) ,
288+ Transform :: Flipped90 => image:: imageops:: flip_vertical ( & image:: imageops:: rotate90 ( & image) ) ,
289+ Transform :: Flipped180 => {
290+ image:: imageops:: flip_vertical ( & image:: imageops:: rotate180 ( & image) )
291+ }
292+ Transform :: Flipped270 => {
293+ image:: imageops:: flip_vertical ( & image:: imageops:: rotate270 ( & image) )
294+ }
295+ _ => unreachable ! ( ) ,
296+ } ;
258297
259298 let clipimage = img. view ( x as u32 , y as u32 , width as u32 , height as u32 ) ;
260299 let pixel = clipimage. get_pixel ( 0 , 0 ) ;
@@ -342,15 +381,33 @@ fn capture_fullscreen(
342381 let Size { width, height } = output. logical_size ( ) ;
343382 let image_info =
344383 state. capture_single_output ( pointer. to_capture_option ( ) , output. clone ( ) ) ?;
345-
346- // Load the captured image
347- let img = image:: imageops:: resize (
348- & image:: ImageBuffer :: from_raw ( image_info. width , image_info. height , image_info. data )
384+ let image =
385+ image:: ImageBuffer :: from_raw ( image_info. width , image_info. height , image_info. data )
349386 . ok_or ( HaruhiImageWriteError :: ImageError ( ImageError :: Parameter (
350387 image:: error:: ParameterError :: from_kind (
351388 image:: error:: ParameterErrorKind :: DimensionMismatch ,
352389 ) ,
353- ) ) ) ?,
390+ ) ) ) ?;
391+ let image = match image_info. transform {
392+ Transform :: Normal => image,
393+ Transform :: _90 => image:: imageops:: rotate90 ( & image) ,
394+ Transform :: _180 => image:: imageops:: rotate180 ( & image) ,
395+ Transform :: _270 => image:: imageops:: rotate270 ( & image) ,
396+ Transform :: Flipped => image:: imageops:: flip_vertical ( & image) ,
397+ Transform :: Flipped90 => {
398+ image:: imageops:: flip_vertical ( & image:: imageops:: rotate90 ( & image) )
399+ }
400+ Transform :: Flipped180 => {
401+ image:: imageops:: flip_vertical ( & image:: imageops:: rotate180 ( & image) )
402+ }
403+ Transform :: Flipped270 => {
404+ image:: imageops:: flip_vertical ( & image:: imageops:: rotate270 ( & image) )
405+ }
406+ _ => unreachable ! ( ) ,
407+ } ;
408+ // Load the captured image
409+ let img = image:: imageops:: resize (
410+ & image,
354411 width as u32 ,
355412 height as u32 ,
356413 image:: imageops:: FilterType :: Gaussian ,
@@ -378,6 +435,7 @@ fn capture_fullscreen(
378435 width : total_width,
379436 height : total_height,
380437 color_type : image:: ColorType :: Rgba8 ,
438+ transform : libharuhishot:: reexport:: Transform :: Normal ,
381439 } ;
382440
383441 write_to_image ( combined_image_info, use_stdout)
@@ -453,6 +511,7 @@ fn write_to_stdout(
453511 width,
454512 height,
455513 color_type,
514+ ..
456515 } : ImageInfo ,
457516) -> Result < HaruhiShotResult , HaruhiImageWriteError > {
458517 let stdout = stdout ( ) ;
@@ -467,6 +526,7 @@ fn write_to_file(
467526 width,
468527 height,
469528 color_type,
529+ ..
470530 } : ImageInfo ,
471531) -> Result < HaruhiShotResult , HaruhiImageWriteError > {
472532 let file = random_file_path ( ) ;
0 commit comments