Add an option to use immich previews (1440p) intead of full images
This commit is contained in:
parent
bbe6cd4d01
commit
88214ca413
5 changed files with 55 additions and 2 deletions
|
|
@ -41,6 +41,7 @@
|
||||||
const configToSend = {
|
const configToSend = {
|
||||||
processing: {
|
processing: {
|
||||||
max_workers: Number(config.processing.max_workers),
|
max_workers: Number(config.processing.max_workers),
|
||||||
|
use_preview: config.processing.use_preview,
|
||||||
face_resolution: {
|
face_resolution: {
|
||||||
enabled: config.processing.face_resolution.enabled,
|
enabled: config.processing.face_resolution.enabled,
|
||||||
min_size: Number(config.processing.face_resolution.min_size),
|
min_size: Number(config.processing.face_resolution.min_size),
|
||||||
|
|
@ -384,6 +385,14 @@
|
||||||
<span class="value">{config.processing.max_workers}</span>
|
<span class="value">{config.processing.max_workers}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="setting-row checkbox-row">
|
||||||
|
<label for="use-preview">
|
||||||
|
<span class="setting-label">Use Preview Images</span>
|
||||||
|
<span class="setting-hint">Download Immich 1440p previews instead of originals (much faster)</span>
|
||||||
|
</label>
|
||||||
|
<input id="use-preview" type="checkbox" bind:checked={config.processing.use_preview} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Time Interval Section -->
|
<!-- Time Interval Section -->
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ export const JOB_STATUS = {
|
||||||
export const DEFAULT_CONFIG = {
|
export const DEFAULT_CONFIG = {
|
||||||
processing: {
|
processing: {
|
||||||
max_workers: 4,
|
max_workers: 4,
|
||||||
|
use_preview: true,
|
||||||
face_resolution: {
|
face_resolution: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
min_size: 80,
|
min_size: 80,
|
||||||
|
|
|
||||||
|
|
@ -495,6 +495,12 @@ pub struct ProcessingConfig {
|
||||||
/// Number of parallel workers for processing.
|
/// Number of parallel workers for processing.
|
||||||
pub max_workers: usize,
|
pub max_workers: usize,
|
||||||
|
|
||||||
|
/// Whether to download Immich preview images (1440p JPEG) instead of originals.
|
||||||
|
/// Preview images are much faster to decode and sufficient for most use cases.
|
||||||
|
/// Disable only if you need full original resolution (e.g., very small faces in high-res photos).
|
||||||
|
#[serde(default = "default_true")]
|
||||||
|
pub use_preview: bool,
|
||||||
|
|
||||||
/// Face resolution validation settings.
|
/// Face resolution validation settings.
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub face_resolution: FaceResolutionConfig,
|
pub face_resolution: FaceResolutionConfig,
|
||||||
|
|
@ -536,6 +542,7 @@ impl Default for ProcessingConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
max_workers: num_cpus(),
|
max_workers: num_cpus(),
|
||||||
|
use_preview: true,
|
||||||
face_resolution: FaceResolutionConfig::default(),
|
face_resolution: FaceResolutionConfig::default(),
|
||||||
blur: BlurConfig::default(),
|
blur: BlurConfig::default(),
|
||||||
brightness: BrightnessConfig::default(),
|
brightness: BrightnessConfig::default(),
|
||||||
|
|
@ -570,6 +577,10 @@ impl ProcessingConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn default_true() -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
fn num_cpus() -> usize {
|
fn num_cpus() -> usize {
|
||||||
std::thread::available_parallelism()
|
std::thread::available_parallelism()
|
||||||
.map(|p| p.get())
|
.map(|p| p.get())
|
||||||
|
|
|
||||||
|
|
@ -240,6 +240,33 @@ impl ImmichClient {
|
||||||
Ok(bytes)
|
Ok(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Download an asset's preview image (1440p JPEG pre-generated by Immich).
|
||||||
|
///
|
||||||
|
/// Much faster to download and decode than the original.
|
||||||
|
/// Falls back to the original if the preview is unavailable.
|
||||||
|
pub async fn download_asset_preview(&self, asset_id: &str) -> Result<bytes::Bytes> {
|
||||||
|
let encoded_id = urlencode(asset_id);
|
||||||
|
let url = format!("{}/assets/{}/thumbnail?size=preview", self.base_url, encoded_id);
|
||||||
|
|
||||||
|
let response = self
|
||||||
|
.client
|
||||||
|
.get(&url)
|
||||||
|
.header("x-api-key", &self.api_key)
|
||||||
|
.send()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
if !response.status().is_success() {
|
||||||
|
return Err(Error::ImmichApi(format!(
|
||||||
|
"Failed to download preview for asset {}: {}",
|
||||||
|
asset_id,
|
||||||
|
response.status()
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
let bytes = response.bytes().await?;
|
||||||
|
Ok(bytes)
|
||||||
|
}
|
||||||
|
|
||||||
/// Get all people from Immich.
|
/// Get all people from Immich.
|
||||||
pub async fn get_people(&self) -> Result<Vec<Person>> {
|
pub async fn get_people(&self) -> Result<Vec<Person>> {
|
||||||
let url = format!("{}/people", self.base_url);
|
let url = format!("{}/people", self.base_url);
|
||||||
|
|
|
||||||
|
|
@ -108,8 +108,13 @@ pub async fn process_single_asset(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Download image
|
// Download image (preview or original based on config)
|
||||||
let image_bytes: Bytes = match client.download_asset(asset_id).await {
|
let download_result = if config.processing.use_preview {
|
||||||
|
client.download_asset_preview(asset_id).await
|
||||||
|
} else {
|
||||||
|
client.download_asset(asset_id).await
|
||||||
|
};
|
||||||
|
let image_bytes: Bytes = match download_result {
|
||||||
Ok(bytes) => bytes,
|
Ok(bytes) => bytes,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
skip_stats.increment("download_failed");
|
skip_stats.increment("download_failed");
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue