截图模块初始化
This commit is contained in:
@@ -232,10 +232,19 @@ pub fn dib_info(dib: &[u8]) -> Option<(u32, u32)> {
|
||||
Some((width as u32, height.abs() as u32))
|
||||
}
|
||||
|
||||
/// 将 CF_DIB 字节转换为 PNG 字节(仅支持 24/32bpp BI_RGB)。
|
||||
/// 将 CF_DIB 字节转换为 PNG 字节(支持 24/32bpp BI_RGB / BI_BITFIELDS)。
|
||||
pub fn dib_to_png(dib: &[u8]) -> Option<Vec<u8>> {
|
||||
use image::codecs::png::PngEncoder;
|
||||
use image::ImageEncoder;
|
||||
|
||||
// 兜底:数据本身就是 PNG / JPEG(极少数来源直接存放压缩数据)
|
||||
if dib.len() >= 4 && &dib[0..4] == b"\x89PNG" {
|
||||
return Some(dib.to_vec());
|
||||
}
|
||||
if dib.len() >= 3 && dib[0] == 0xFF && dib[1] == 0xD8 && dib[2] == 0xFF {
|
||||
return Some(dib.to_vec());
|
||||
}
|
||||
|
||||
if dib.len() < 40 {
|
||||
return None;
|
||||
}
|
||||
@@ -244,7 +253,14 @@ pub fn dib_to_png(dib: &[u8]) -> Option<Vec<u8>> {
|
||||
let height_raw = i32::from_le_bytes([dib[8], dib[9], dib[10], dib[11]]);
|
||||
let bpp = u16::from_le_bytes([dib[14], dib[15]]);
|
||||
let compression = u32::from_le_bytes([dib[16], dib[17], dib[18], dib[19]]);
|
||||
if width <= 0 || compression != 0 {
|
||||
if width <= 0 {
|
||||
return None;
|
||||
}
|
||||
// 接受 BI_RGB(0) 和 BI_BITFIELDS(3)。
|
||||
// Windows 截图工具(Win+Shift+S / 截图工具)常用 BI_BITFIELDS 标记 32bpp BGRA,
|
||||
// 像素数据本身未压缩,与 BI_RGB 解码方式一致。
|
||||
// 拒绝 BI_RLE4/8(1/2) 和 BI_JPEG/PNG(4/5) 等真正压缩格式。
|
||||
if compression != 0 && compression != 3 {
|
||||
return None;
|
||||
}
|
||||
if bpp != 24 && bpp != 32 {
|
||||
@@ -269,7 +285,8 @@ pub fn dib_to_png(dib: &[u8]) -> Option<Vec<u8>> {
|
||||
rgba[dp] = dib[sp + 2]; // R
|
||||
rgba[dp + 1] = dib[sp + 1]; // G
|
||||
rgba[dp + 2] = dib[sp]; // B
|
||||
rgba[dp + 3] = 255; // A
|
||||
// 32bpp 保留 alpha 通道(截图工具常用);24bpp 不透明
|
||||
rgba[dp + 3] = if bpp == 32 { dib[sp + 3] } else { 255 };
|
||||
}
|
||||
}
|
||||
let mut buf = Vec::new();
|
||||
|
||||
Reference in New Issue
Block a user