diff --git a/crates/desktop/artcraft/src/core/utils/mod.rs b/crates/desktop/artcraft/src/core/utils/mod.rs index f3ac67fd4c..5ea5eb93de 100644 --- a/crates/desktop/artcraft/src/core/utils/mod.rs +++ b/crates/desktop/artcraft/src/core/utils/mod.rs @@ -11,4 +11,5 @@ pub mod save_base64_image_to_temp_dir; pub mod simple_http_download; pub mod simple_http_download_to_tempfile; pub mod task_database_pending_statuses; +pub mod upload_bytes_to_media_file; pub mod window; \ No newline at end of file diff --git a/crates/desktop/artcraft/src/core/utils/upload_bytes_to_media_file/mod.rs b/crates/desktop/artcraft/src/core/utils/upload_bytes_to_media_file/mod.rs new file mode 100644 index 0000000000..9f4a49e121 --- /dev/null +++ b/crates/desktop/artcraft/src/core/utils/upload_bytes_to_media_file/mod.rs @@ -0,0 +1,2 @@ +pub mod upload_image_bytes_as_media_file; +pub mod upload_mask_image_bytes_as_media_file; diff --git a/crates/desktop/artcraft/src/core/utils/upload_bytes_to_media_file/upload_image_bytes_as_media_file.rs b/crates/desktop/artcraft/src/core/utils/upload_bytes_to_media_file/upload_image_bytes_as_media_file.rs new file mode 100644 index 0000000000..a188d84e9f --- /dev/null +++ b/crates/desktop/artcraft/src/core/utils/upload_bytes_to_media_file/upload_image_bytes_as_media_file.rs @@ -0,0 +1,37 @@ +use log::info; + +use artcraft_client::credentials::storyteller_credential_set::StorytellerCredentialSet; +use artcraft_client::endpoints::media_files::upload_image_media_file_from_bytes::{ + upload_image_media_file_from_bytes, ImageType, UploadImageBytesArgs, +}; +use artcraft_client::utils::api_host::ApiHost; +use tokens::tokens::media_files::MediaFileToken; + +use crate::core::commands::enqueue::generate_error::GenerateError; + +/// Upload raw image bytes to ArtCraft, returning the resulting MediaFileToken. +/// +/// This is NOT marked as an intermediate system file — the image will appear +/// in the user's gallery. +pub async fn upload_image_bytes_as_media_file( + creds: &StorytellerCredentialSet, + api_host: &ApiHost, + image_bytes: Vec, +) -> Result { + info!("Uploading image bytes ({} bytes) as media file...", image_bytes.len()); + + let result = upload_image_media_file_from_bytes(UploadImageBytesArgs { + api_host, + maybe_creds: Some(creds), + image_bytes, + image_type: ImageType::Png, + is_intermediate_system_file: false, + }).await.map_err(|err| { + log::error!("Failed to upload image bytes as media file: {:?}", err); + GenerateError::from(err) + })?; + + info!("Uploaded image bytes as media file: {}", result.media_file_token.as_str()); + + Ok(result.media_file_token) +} diff --git a/crates/desktop/artcraft/src/core/utils/upload_bytes_to_media_file/upload_mask_image_bytes_as_media_file.rs b/crates/desktop/artcraft/src/core/utils/upload_bytes_to_media_file/upload_mask_image_bytes_as_media_file.rs new file mode 100644 index 0000000000..d913af68a7 --- /dev/null +++ b/crates/desktop/artcraft/src/core/utils/upload_bytes_to_media_file/upload_mask_image_bytes_as_media_file.rs @@ -0,0 +1,47 @@ +use log::{error, info}; + +use artcraft_client::credentials::storyteller_credential_set::StorytellerCredentialSet; +use artcraft_client::endpoints::media_files::upload_image_media_file_from_bytes::{ + upload_image_media_file_from_bytes, ImageType, UploadImageBytesArgs, +}; +use artcraft_client::utils::api_host::ApiHost; +use images::mask_images::normalize_image_bytes_to_flux_mask::normalize_image_bytes_to_flux_mask; +use tokens::tokens::media_files::MediaFileToken; + +use crate::core::commands::enqueue::generate_error::GenerateError; + +/// Upload raw mask image bytes to ArtCraft, returning the resulting MediaFileToken. +/// +/// The mask bytes are first normalized via `normalize_image_bytes_to_flux_mask` +/// (transparent pixels → black/ignore, opaque pixels → white/interest region), +/// then uploaded as an intermediate system file (hidden from the user's gallery). +pub async fn upload_mask_image_bytes_as_media_file( + creds: &StorytellerCredentialSet, + api_host: &ApiHost, + mask_image_bytes: &[u8], +) -> Result { + info!("Normalizing mask image bytes ({} bytes)...", mask_image_bytes.len()); + + let normalized = normalize_image_bytes_to_flux_mask(mask_image_bytes) + .map_err(|err| { + error!("Failed to normalize mask image bytes: {:?}", err); + GenerateError::AnyhowError(anyhow::anyhow!("Failed to normalize mask image bytes")) + })?; + + info!("Uploading normalized mask ({} bytes) as intermediate system file...", normalized.0.len()); + + let result = upload_image_media_file_from_bytes(UploadImageBytesArgs { + api_host, + maybe_creds: Some(creds), + image_bytes: normalized.0, + image_type: ImageType::Png, + is_intermediate_system_file: true, + }).await.map_err(|err| { + error!("Failed to upload mask image bytes: {:?}", err); + GenerateError::from(err) + })?; + + info!("Uploaded mask as media file: {}", result.media_file_token.as_str()); + + Ok(result.media_file_token) +}