diff --git a/packages/media/cpp/dist/pm-image.exe b/packages/media/cpp/dist/pm-image.exe
index 077f6735..12ae5e73 100644
Binary files a/packages/media/cpp/dist/pm-image.exe and b/packages/media/cpp/dist/pm-image.exe differ
diff --git a/packages/media/cpp/dist/pm-image.pdb b/packages/media/cpp/dist/pm-image.pdb
index 8bfb6215..96a3e612 100644
Binary files a/packages/media/cpp/dist/pm-image.pdb and b/packages/media/cpp/dist/pm-image.pdb differ
diff --git a/packages/media/cpp/src/core/transform.cpp b/packages/media/cpp/src/core/transform.cpp
index 3b3bce09..b372f7b8 100644
--- a/packages/media/cpp/src/core/transform.cpp
+++ b/packages/media/cpp/src/core/transform.cpp
@@ -119,7 +119,7 @@ static TransformResult call_gemini(
std::string mime = mime_from_ext(fs::path(input_path).extension().string());
std::string b64 = base64_encode(img_bytes.data(), img_bytes.size());
- // Build request JSON
+ // Build request JSON (Gemini 3 REST API)
json req_body = {
{"contents", json::array({
{{"parts", json::array({
@@ -133,7 +133,7 @@ static TransformResult call_gemini(
};
std::string url = "https://generativelanguage.googleapis.com/v1beta/models/"
- + opts.model + ":generateContent?key=" + opts.api_key;
+ + opts.model + ":generateContent";
std::string body_str = req_body.dump();
@@ -150,6 +150,8 @@ static TransformResult call_gemini(
std::string response_str;
struct curl_slist* headers = nullptr;
headers = curl_slist_append(headers, "Content-Type: application/json");
+ std::string auth_header = "x-goog-api-key: " + opts.api_key;
+ headers = curl_slist_append(headers, auth_header.c_str());
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
diff --git a/packages/media/cpp/src/main.cpp b/packages/media/cpp/src/main.cpp
index d005a9bf..c038d393 100644
--- a/packages/media/cpp/src/main.cpp
+++ b/packages/media/cpp/src/main.cpp
@@ -151,7 +151,7 @@ int main(int argc, char **argv) {
std::string tf_output;
std::string tf_prompt;
std::string tf_provider = "google";
- std::string tf_model = "gemini-2.0-flash-exp";
+ std::string tf_model = "gemini-3-pro-image-preview";
std::string tf_api_key;
auto *transform_cmd = app.add_subcommand("transform", "AI image editing (Gemini / Google)");
@@ -159,7 +159,7 @@ int main(int argc, char **argv) {
transform_cmd->add_option("output", tf_output, "Output path (omit = auto from input + prompt)");
transform_cmd->add_option("-p,--prompt", tf_prompt, "Editing prompt")->required(true);
transform_cmd->add_option("--provider", tf_provider, "AI provider (google)")->default_val("google");
- transform_cmd->add_option("--model", tf_model, "Model name")->default_val("gemini-2.0-flash-exp");
+ transform_cmd->add_option("--model", tf_model, "Model name")->default_val("gemini-3-pro-image-preview");
transform_cmd->add_option("--api-key", tf_api_key, "API key (or set IMAGE_TRANSFORM_GOOGLE_API_KEY env)");
// ── serve ───────────────────────────────────────────────────────────
diff --git a/packages/media/cpp/src/win/ui_next/Resource.h b/packages/media/cpp/src/win/ui_next/Resource.h
index be2c869c..283f152b 100644
--- a/packages/media/cpp/src/win/ui_next/Resource.h
+++ b/packages/media/cpp/src/win/ui_next/Resource.h
@@ -25,10 +25,17 @@
#define IDC_CHK_AUTOROT 608
#define IDC_CHK_STRIP 609
+// AI Transform dialog controls
+#define IDD_TRANSFORM_PROMPT 700
+#define IDC_EDIT_PROMPT 701
+#define IDC_STATIC_PROMPT_LABEL 702
+
// User messages
#define UWM_QUEUE_PROGRESS (WM_USER + 100)
#define UWM_QUEUE_DONE (WM_USER + 101)
#define UWM_IMAGELOADED (WM_USER + 102)
#define UWM_QUEUE_ITEM_CLICKED (WM_USER + 103)
+#define UWM_TRANSFORM_PROGRESS (WM_USER + 104)
+#define UWM_TRANSFORM_DONE (WM_USER + 105)
#endif // PM_UI_RESOURCE_H
diff --git a/packages/media/cpp/src/win/ui_next/Ribbon.xml b/packages/media/cpp/src/win/ui_next/Ribbon.xml
index 92fe55ea..9c20e970 100644
--- a/packages/media/cpp/src/win/ui_next/Ribbon.xml
+++ b/packages/media/cpp/src/win/ui_next/Ribbon.xml
@@ -74,6 +74,29 @@
+
+
+
+ AI Transform
+
+
+
+
+ Transform
+
+
+
+
+ Transform
+
+
+ res/TransformL.bmp
+
+
+ res/TransformS.bmp
+
+
+
@@ -121,6 +144,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/media/cpp/src/win/ui_next/gen_icons.ps1 b/packages/media/cpp/src/win/ui_next/gen_icons.ps1
index 4f4de2fd..8fd38d84 100644
--- a/packages/media/cpp/src/win/ui_next/gen_icons.ps1
+++ b/packages/media/cpp/src/win/ui_next/gen_icons.ps1
@@ -42,4 +42,8 @@ Convert-PngToBmp "$resDir\16x16_0300\cross.png" "$resDir\ClearS.bmp" 16
# Resize -> arrow_out.png
Convert-PngToBmp "$resDir\32x32_0060\arrow_out.png" "$resDir\ResizeL.bmp" 32
+# AI Transform -> paintbrush.png
+Convert-PngToBmp "$resDir\32x32_0700\paintcan.png" "$resDir\TransformL.bmp" 32
+Convert-PngToBmp "$resDir\16x16_0700\paintbrush.png" "$resDir\TransformS.bmp" 16
+
Write-Output "Done."
diff --git a/packages/media/cpp/src/win/ui_next/res/TransformL.bmp b/packages/media/cpp/src/win/ui_next/res/TransformL.bmp
new file mode 100644
index 00000000..0d48f757
Binary files /dev/null and b/packages/media/cpp/src/win/ui_next/res/TransformL.bmp differ
diff --git a/packages/media/cpp/src/win/ui_next/res/TransformS.bmp b/packages/media/cpp/src/win/ui_next/res/TransformS.bmp
new file mode 100644
index 00000000..5fc7283b
Binary files /dev/null and b/packages/media/cpp/src/win/ui_next/res/TransformS.bmp differ
diff --git a/packages/media/cpp/tests/assets/in/DSC01177_remove_background_white_studio_product_s.JPG b/packages/media/cpp/tests/assets/in/DSC01177_remove_background_white_studio_product_s.JPG
new file mode 100644
index 00000000..f3a078bf
Binary files /dev/null and b/packages/media/cpp/tests/assets/in/DSC01177_remove_background_white_studio_product_s.JPG differ