|
1 | 1 | #![allow(dead_code)] |
2 | 2 | use std::sync::Arc; |
3 | 3 |
|
4 | | -use skia_safe::{surfaces, EncodedImageFormat}; |
| 4 | +use skia_safe::surfaces; |
5 | 5 |
|
6 | 6 | use canvas_core::image_asset::ImageAsset; |
7 | 7 |
|
@@ -201,91 +201,90 @@ pub(crate) fn create_image_bitmap_internal( |
201 | 201 | resize_height: f32, |
202 | 202 | output: &ImageAsset, |
203 | 203 | ) { |
204 | | - let mut out_width = image.width() as f32; |
205 | | - let mut out_height = image.height() as f32; |
| 204 | + let img_w = image.width() as f32; |
| 205 | + let img_h = image.height() as f32; |
206 | 206 |
|
207 | | - if resize_width <= 0. && resize_height > 0. { |
208 | | - out_width = image.width() as f32 + resize_height / image.height() as f32; |
209 | | - } |
210 | | - |
211 | | - if resize_height <= 0. && resize_width > 0. { |
212 | | - out_height = image.height() as f32 + resize_width / image.width() as f32; |
213 | | - } |
| 207 | + // Only one of resize_width / resize_height being set means proportional scale. |
| 208 | + let (mut out_width, mut out_height) = (img_w, img_h); |
214 | 209 |
|
215 | 210 | if resize_width > 0. && resize_height > 0. { |
216 | 211 | out_width = resize_width; |
217 | 212 | out_height = resize_height; |
| 213 | + } else if resize_width > 0. { |
| 214 | + let ratio = resize_width / img_w; |
| 215 | + out_width = resize_width; |
| 216 | + out_height = img_h * ratio; |
| 217 | + } else if resize_height > 0. { |
| 218 | + let ratio = resize_height / img_h; |
| 219 | + out_width = img_w * ratio; |
| 220 | + out_height = resize_height; |
218 | 221 | } |
219 | 222 |
|
220 | | - let source_rect; |
221 | | - |
222 | | - match rect { |
223 | | - None => { |
224 | | - source_rect = |
225 | | - skia_safe::Rect::from_xywh(0., 0., image.width() as f32, image.height() as f32); |
226 | | - } |
227 | | - Some(rect) => { |
228 | | - source_rect = skia_safe::Rect::from_xywh(rect.0, rect.1, rect.2, rect.3); |
| 223 | + let source_rect = match rect { |
| 224 | + None => skia_safe::Rect::from_xywh(0., 0., img_w, img_h), |
| 225 | + Some(r) => { |
| 226 | + let sr = skia_safe::Rect::from_xywh(r.0, r.1, r.2, r.3); |
229 | 227 | if resize_width == 0. && resize_height == 0. { |
230 | | - out_width = rect.1; |
231 | | - out_height = rect.2; |
| 228 | + out_width = sr.width(); |
| 229 | + out_height = sr.height(); |
232 | 230 | } |
| 231 | + sr |
233 | 232 | } |
234 | | - } |
| 233 | + }; |
| 234 | + |
| 235 | + let alpha_type = ImageBitmapPremultiplyAlpha::from(premultiply_alpha).into(); |
| 236 | + let color_space = ImageBitmapColorSpaceConversion::from(color_space_conversion).to_color_space(); |
235 | 237 |
|
236 | 238 | let image_info = skia_safe::ImageInfo::new( |
237 | 239 | (source_rect.width() as i32, source_rect.height() as i32), |
238 | 240 | skia_safe::ColorType::RGBA8888, |
239 | | - ImageBitmapPremultiplyAlpha::from(premultiply_alpha).into(), |
240 | | - ImageBitmapColorSpaceConversion::from(color_space_conversion).to_color_space(), |
| 241 | + alpha_type, |
| 242 | + color_space, |
241 | 243 | ); |
242 | 244 |
|
243 | | - match surfaces::raster(&image_info, Some((source_rect.width() * 4.) as usize), None) { |
244 | | - None => {} |
245 | | - Some(mut surface) => { |
246 | | - let canvas = surface.canvas(); |
247 | | - if flip_y { |
248 | | - canvas.translate(skia_safe::Vector::new(0., source_rect.height())); |
249 | | - canvas.scale((1., -1.)); |
250 | | - } |
| 245 | + let mut surface = match surfaces::raster(&image_info, Some((source_rect.width() * 4.) as usize), None) { |
| 246 | + None => return, |
| 247 | + Some(s) => s, |
| 248 | + }; |
251 | 249 |
|
252 | | - let mut paint = skia_safe::Paint::default(); |
253 | | - paint.set_anti_alias(true); |
254 | | - |
255 | | - surface |
256 | | - .canvas() |
257 | | - .draw_image(&image, (source_rect.x(), source_rect.y()), Some(&paint)); |
258 | | - |
259 | | - let image = surface.image_snapshot(); |
260 | | - |
261 | | - if image.width() != out_width as i32 && image.height() != out_height as i32 { |
262 | | - let resize_info = image_info.with_dimensions((out_width as i32, out_height as i32)); |
263 | | - |
264 | | - let mut bytes = vec![0_u8; (out_width * out_height * 4.) as usize]; |
265 | | - if let Some(pixel_map) = skia_safe::Pixmap::new( |
266 | | - &resize_info, |
267 | | - bytes.as_mut_slice(), |
268 | | - (out_width * 4.) as usize, |
269 | | - ) { |
270 | | - let _ = image.scale_pixels( |
271 | | - &pixel_map, |
272 | | - ImageBitmapResizeQuality::from(resize_quality).to_quality(), |
273 | | - None, |
274 | | - ); |
275 | | - |
276 | | - let data = pixel_map.encode(EncodedImageFormat::PNG, 75); |
277 | | - |
278 | | - if let Some(data) = data { |
279 | | - output.load_from_bytes(data.as_slice()); |
280 | | - }; |
281 | | - } |
282 | | - } else { |
283 | | - let encoded = image.encode(None, EncodedImageFormat::PNG, 75); |
284 | | - |
285 | | - if let Some(encoded) = encoded { |
286 | | - output.load_from_bytes(encoded.as_bytes()); |
287 | | - } |
288 | | - } |
| 250 | + { |
| 251 | + let canvas = surface.canvas(); |
| 252 | + if flip_y { |
| 253 | + canvas.translate(skia_safe::Vector::new(0., source_rect.height())); |
| 254 | + canvas.scale((1., -1.)); |
| 255 | + } |
| 256 | + let mut paint = skia_safe::Paint::default(); |
| 257 | + paint.set_anti_alias(true); |
| 258 | + canvas.draw_image(&image, (-source_rect.x(), -source_rect.y()), Some(&paint)); |
| 259 | + } |
| 260 | + |
| 261 | + let snapshot = surface.image_snapshot(); |
| 262 | + let needs_resize = snapshot.width() != out_width as i32 || snapshot.height() != out_height as i32; |
| 263 | + |
| 264 | + if needs_resize { |
| 265 | + let resize_info = image_info.with_dimensions((out_width as i32, out_height as i32)); |
| 266 | + let row_bytes = (out_width * 4.) as usize; |
| 267 | + let mut pixels = vec![0_u8; out_height as usize * row_bytes]; |
| 268 | + |
| 269 | + if let Some(pixel_map) = skia_safe::Pixmap::new(&resize_info, pixels.as_mut_slice(), row_bytes) { |
| 270 | + let _ = snapshot.scale_pixels( |
| 271 | + &pixel_map, |
| 272 | + ImageBitmapResizeQuality::from(resize_quality).to_quality(), |
| 273 | + None, |
| 274 | + ); |
| 275 | + } |
| 276 | + output.load_from_raw_bytes_rgba(out_width as u32, out_height as u32, pixels); |
| 277 | + } else { |
| 278 | + let row_bytes = (snapshot.width() * 4) as usize; |
| 279 | + let mut pixels = vec![0_u8; snapshot.height() as usize * row_bytes]; |
| 280 | + let read_info = skia_safe::ImageInfo::new( |
| 281 | + snapshot.dimensions(), |
| 282 | + skia_safe::ColorType::RGBA8888, |
| 283 | + alpha_type, |
| 284 | + None, |
| 285 | + ); |
| 286 | + if snapshot.read_pixels(&read_info, pixels.as_mut_slice(), row_bytes, (0, 0), skia_safe::image::CachingHint::Allow) { |
| 287 | + output.load_from_raw_bytes_rgba(snapshot.width() as u32, snapshot.height() as u32, pixels); |
289 | 288 | } |
290 | 289 | } |
291 | 290 | } |
@@ -492,7 +491,7 @@ pub fn create_image_asset_encoded_raw( |
492 | 491 | premultiply_alpha, |
493 | 492 | color_space_conversion, |
494 | 493 | resize_quality, |
495 | | - resize_height, |
496 | 494 | resize_width, |
| 495 | + resize_height, |
497 | 496 | ))) as i64 |
498 | 497 | } |
0 commit comments