@@ -1,104 +0,0 @@
|
||||
//! 探测 SegmentCommonImage 在小尺寸(480p 级)输入下 crop/mask 的输出尺寸行为。
|
||||
//!
|
||||
//! cargo run -p platform-matting --example crop_size_probe
|
||||
|
||||
use std::io::Cursor;
|
||||
use std::path::Path;
|
||||
|
||||
use image::{DynamicImage, GenericImage, ImageFormat, Rgba, RgbaImage};
|
||||
use platform_matting::{
|
||||
DEFAULT_IMAGESEG_ENDPOINT, MattingClient, MattingConfig, SegmentCommonImageRequest,
|
||||
SegmentReturnForm,
|
||||
};
|
||||
|
||||
fn load_env_files() {
|
||||
for candidate in [
|
||||
".env",
|
||||
".env.local",
|
||||
".env.secrets.local",
|
||||
"../.env",
|
||||
"../.env.local",
|
||||
"../.env.secrets.local",
|
||||
] {
|
||||
if Path::new(candidate).exists() {
|
||||
let _ = dotenvy::from_path_override(candidate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_png(image: &DynamicImage) -> Vec<u8> {
|
||||
let mut buffer = Cursor::new(Vec::new());
|
||||
image
|
||||
.write_to(&mut buffer, ImageFormat::Png)
|
||||
.expect("PNG 编码应成功");
|
||||
buffer.into_inner()
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
load_env_files();
|
||||
|
||||
let input_path = std::env::args().nth(1).unwrap_or_else(|| {
|
||||
r"C:\Users\lingh\Downloads\gpt-image-2-elf-archer-2048x2048.png".to_string()
|
||||
});
|
||||
let source = image::open(&input_path).expect("测试图片应可解码");
|
||||
|
||||
// 变体1:等比缩到 480(模拟 1:1 480p 视频帧,主体居中)
|
||||
let centered = source.resize(480, 480, image::imageops::FilterType::CatmullRom);
|
||||
|
||||
// 变体2:把 360 尺寸的主体贴到 640x480 画布左上角(模拟横版帧、主体偏移)
|
||||
let small = source.resize(360, 360, image::imageops::FilterType::CatmullRom);
|
||||
let corner_pixel = centered.to_rgba8().get_pixel(0, 0).0;
|
||||
let mut offset_canvas = RgbaImage::from_pixel(640, 480, Rgba(corner_pixel));
|
||||
offset_canvas
|
||||
.copy_from(&small.to_rgba8(), 20, 40)
|
||||
.expect("贴图应成功");
|
||||
let offset = DynamicImage::ImageRgba8(offset_canvas);
|
||||
|
||||
let matting_config = MattingConfig::new(
|
||||
std::env::var("ALIYUN_IMAGESEG_ENDPOINT")
|
||||
.unwrap_or_else(|_| DEFAULT_IMAGESEG_ENDPOINT.to_string()),
|
||||
std::env::var("ALIBABA_CLOUD_ACCESS_KEY_ID").expect("需要 ALIBABA_CLOUD_ACCESS_KEY_ID"),
|
||||
std::env::var("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
|
||||
.expect("需要 ALIBABA_CLOUD_ACCESS_KEY_SECRET"),
|
||||
)
|
||||
.expect("抠图配置应有效");
|
||||
let client = MattingClient::new(matting_config).expect("客户端应可构建");
|
||||
let http_client = reqwest::Client::new();
|
||||
|
||||
for (label, variant) in [("居中480x480", ¢ered), ("偏移640x480", &offset)] {
|
||||
let bytes = encode_png(variant);
|
||||
let temp_url = client
|
||||
.upload_temp_image(bytes, &format!("probe-{label}.png"), "image/png")
|
||||
.await
|
||||
.expect("上传临时桶应成功");
|
||||
|
||||
for return_form in [None, Some(SegmentReturnForm::Crop), Some(SegmentReturnForm::Mask)] {
|
||||
let result = client
|
||||
.segment_common_image(SegmentCommonImageRequest {
|
||||
image_url: temp_url.clone(),
|
||||
return_form,
|
||||
})
|
||||
.await
|
||||
.expect("抠图调用应成功");
|
||||
let output_bytes = http_client
|
||||
.get(&result.image_url)
|
||||
.send()
|
||||
.await
|
||||
.expect("下载结果应成功")
|
||||
.bytes()
|
||||
.await
|
||||
.expect("读取结果字节应成功");
|
||||
let output = image::load_from_memory(&output_bytes).expect("结果应可解码");
|
||||
println!(
|
||||
"{label} 输入 {}x{} -> {} 输出 {}x{} (alpha通道: {})",
|
||||
variant.width(),
|
||||
variant.height(),
|
||||
return_form.map_or("默认(不传)".to_string(), |f| format!("{f:?}")),
|
||||
output.width(),
|
||||
output.height(),
|
||||
output.color().has_alpha()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user