fix: add alpha channel input for Qwen Image 2.1 and relative docs (#2021)

This commit is contained in:
Weiqi Gao authored and GitHub committed 2026-09-22 21:45:06 +08:00
1 parent e01206574b
commit e112ab5a50
12 files changed
+125 -50

No files matched your search

+5 -2
View File
@@ -735,12 +735,15 @@ Any image field accepts:
Channel expectations:
- `init_image`: 3 channels
- `ref_images[]`: 3 channels
- `init_image`: native channels (3 or 4); alpha is preserved and applied per model
- `ref_images[]`: native channels (3 or 4); alpha is preserved and applied per model
- `control_image`: 3 channels
- `ip_adapter_image`: 3 channels
- `mask_image`: 1 channel
Models that support RGBA (e.g. Qwen-Image 2.1) use the alpha channel of `init_image`
and `ref_images[]`. RGB-only models drop it, so sending RGBA is safe for every model.
If omitted or null:
- single-image fields map to an empty `sd_image_t`
+22 -19
View File
@@ -158,19 +158,20 @@ static bool build_openai_edit_request(const httplib::Request& req,
request.gen_params.batch_count = n;
for (auto& bytes : images_bytes) {
int img_w = 0;
int img_h = 0;
uint8_t* raw_pixels = load_image_from_memory(
reinterpret_cast<const char*>(bytes.data()),
static_cast<int>(bytes.size()),
img_w, img_h,
0, 0, 3);
int img_w = 0;
int img_h = 0;
int resolved_channel = 0;
uint8_t* raw_pixels = load_image_from_memory(
reinterpret_cast<const char*>(bytes.data()),
static_cast<int>(bytes.size()),
img_w, img_h, resolved_channel,
0, 0, 0);
if (raw_pixels == nullptr) {
continue;
}
const bool is_first_ref_image = request.gen_params.ref_images.empty();
SDImageOwner image_owner({(uint32_t)img_w, (uint32_t)img_h, 3, raw_pixels});
SDImageOwner image_owner({(uint32_t)img_w, (uint32_t)img_h, (uint32_t)resolved_channel, raw_pixels});
request.gen_params.set_width_and_height_if_unset(image_owner.get().width, image_owner.get().height);
if (is_first_ref_image) {
@@ -181,15 +182,16 @@ static bool build_openai_edit_request(const httplib::Request& req,
init_h = request.gen_params.height;
}
int init_img_w = 0;
int init_img_h = 0;
uint8_t* init_pixels = load_image_from_memory(
reinterpret_cast<const char*>(bytes.data()),
static_cast<int>(bytes.size()),
init_img_w, init_img_h,
init_w, init_h, 3);
int init_img_w = 0;
int init_img_h = 0;
int init_resolved_channel = 0;
uint8_t* init_pixels = load_image_from_memory(
reinterpret_cast<const char*>(bytes.data()),
static_cast<int>(bytes.size()),
init_img_w, init_img_h, init_resolved_channel,
init_w, init_h, 0);
if (init_pixels != nullptr) {
request.gen_params.init_image.reset({(uint32_t)init_img_w, (uint32_t)init_img_h, 3, init_pixels});
request.gen_params.init_image.reset({(uint32_t)init_img_w, (uint32_t)init_img_h, (uint32_t)init_resolved_channel, init_pixels});
}
}
@@ -203,13 +205,14 @@ static bool build_openai_edit_request(const httplib::Request& req,
expected_width = request.gen_params.width;
expected_height = request.gen_params.height;
}
int mask_w = 0;
int mask_h = 0;
int mask_w = 0;
int mask_h = 0;
int mask_channel = 0;
uint8_t* mask_raw = load_image_from_memory(
reinterpret_cast<const char*>(mask_bytes.data()),
static_cast<int>(mask_bytes.size()),
mask_w, mask_h,
mask_w, mask_h, mask_channel,
expected_width, expected_height, 1);
request.gen_params.mask_image.reset({(uint32_t)mask_w, (uint32_t)mask_h, 1, mask_raw});
const sd_image_t& mask_image = request.gen_params.mask_image.get();
+2 -2
View File
@@ -199,7 +199,7 @@ static bool build_sdapi_img_gen_request(const json& j,
if (j.contains("init_images") && j["init_images"].is_array() && !j["init_images"].empty()) {
if (decode_base64_image(j["init_images"][0].get<std::string>(),
3,
0,
expected_width,
expected_height,
request.gen_params.init_image)) {
@@ -243,7 +243,7 @@ static bool build_sdapi_img_gen_request(const json& j,
}
SDImageOwner image_owner;
if (decode_base64_image(extra_image.get<std::string>(),
3,
0,
request.gen_params.auto_resize_ref_image && request.gen_params.width_and_height_are_set()
? request.gen_params.width
: 0,