Created
December 24, 2021 03:19
Revisions
-
gyk created this gist
Dec 24, 2021 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,87 @@ // Improvements over NWG's built-in implementation: // // - High quality interpolation mode // - Crop non-square images fn load_and_resize_image(decoder: &nwg::ImageDecoder, data: &[u8]) -> Result<Bitmap> { use winapi::shared::windef::{HBITMAP, HDC}; use winapi::um::wincodec::{ IWICBitmapScaler, IWICBitmapSource, WICBitmapInterpolationModeHighQualityCubic, }; use winapi::um::wingdi::{ BitBlt, CreateCompatibleBitmap, CreateCompatibleDC, DeleteDC, SelectObject, SRCCOPY, }; let image_frame = decoder.from_stream(data)?.frame(0)?; // Resize let (w, h) = image_frame.size(); let thumb_size = scaled_thumb_size(); let (w, h) = if w >= h { (thumb_size * w / h, thumb_size) } else { (thumb_size, thumb_size * h / w) }; let bitmap = unsafe { let mut scaler: *mut IWICBitmapScaler = ptr::null_mut(); (&*decoder.factory).CreateBitmapScaler(&mut scaler); let image_source = image_frame.frame as *const IWICBitmapSource; (&*scaler).Initialize( image_source, w, h, WICBitmapInterpolationModeHighQualityCubic, ); nwg::ImageData { frame: scaler as *mut IWICBitmapSource, } .as_bitmap()? }; if w == thumb_size && h == thumb_size { return Ok(bitmap); } // Crop unsafe { let hdc_null: HDC = mem::zeroed(); let hdc_src = CreateCompatibleDC(hdc_null); let bmp_src = bitmap.handle; SelectObject(hdc_src, bmp_src); let hdc_dst = CreateCompatibleDC(hdc_null); let bmp_dst: HBITMAP = CreateCompatibleBitmap(hdc_src, thumb_size as i32, thumb_size as i32); SelectObject(hdc_dst, bmp_dst as *mut _); BitBlt( hdc_dst, 0, 0, thumb_size as i32, thumb_size as i32, hdc_src, (w - thumb_size) as i32 / 2, (h - thumb_size) as i32 / 2, SRCCOPY, ); DeleteDC(hdc_src); DeleteDC(hdc_dst); #[allow(dead_code)] struct MyBitmap { handle: *mut std::ffi::c_void, owned: bool, } let my_bmp = MyBitmap { handle: bmp_dst as *mut _, owned: true, }; let bmp: Bitmap = mem::transmute(my_bmp); Ok(bmp) } }