Move UriGlideRenderer to lib:image-editor.

This commit is contained in:
Alex Hart
2026-01-29 12:37:21 -04:00
committed by Greyson Parrelli
parent 7bd3482367
commit 7823d4f49f
9 changed files with 103 additions and 48 deletions

View File

@@ -43,9 +43,9 @@ import org.signal.camera.CameraScreenEvents
import org.signal.camera.CameraScreenViewModel
import org.signal.camera.VideoCaptureResult
import org.signal.camera.VideoOutput
import org.signal.camera.hud.StringResources
import org.signal.camera.hud.StandardCameraHud
import org.signal.camera.hud.StandardCameraHudEvents
import org.signal.camera.hud.StringResources
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.compose.ComposeFragment

View File

@@ -45,6 +45,7 @@ import org.signal.imageeditor.core.model.EditorModel;
import org.signal.imageeditor.core.renderers.BezierDrawingRenderer;
import org.signal.imageeditor.core.renderers.FaceBlurRenderer;
import org.signal.imageeditor.core.renderers.MultiLineTextRenderer;
import org.signal.imageeditor.core.renderers.UriGlideRenderer;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.animation.ResizeAnimation;
import org.thoughtcrime.securesms.attachments.AttachmentSaver;

View File

@@ -174,47 +174,6 @@ public class BitmapUtil {
}
}
@WorkerThread
public static <T> Bitmap createScaledBitmap(Context context, T model, int maxWidth, int maxHeight)
throws BitmapDecodingException
{
try {
return Glide.with(context.getApplicationContext())
.asBitmap()
.load(model)
.centerInside()
.submit(maxWidth, maxHeight)
.get();
} catch (InterruptedException | ExecutionException e) {
throw new BitmapDecodingException(e);
}
}
@WorkerThread
public static Bitmap createScaledBitmap(Bitmap bitmap, int maxWidth, int maxHeight) {
if (bitmap.getWidth() <= maxWidth && bitmap.getHeight() <= maxHeight) {
return bitmap;
}
if (maxWidth <= 0 || maxHeight <= 0) {
return bitmap;
}
int newWidth = maxWidth;
int newHeight = maxHeight;
float widthRatio = bitmap.getWidth() / (float) maxWidth;
float heightRatio = bitmap.getHeight() / (float) maxHeight;
if (widthRatio > heightRatio) {
newHeight = (int) (bitmap.getHeight() / widthRatio);
} else {
newWidth = (int) (bitmap.getWidth() / heightRatio);
}
return Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);
}
public static @NonNull CompressFormat getCompressFormatForContentType(@Nullable String contentType) {
if (contentType == null) return CompressFormat.JPEG;

View File

@@ -21,7 +21,6 @@ import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.ViewModelProvider;
import org.signal.core.ui.compose.SignalIcons;
import org.signal.core.util.logging.Log;
import org.signal.imageeditor.core.ImageEditorView;
import org.signal.imageeditor.core.model.EditorElement;
@@ -32,7 +31,7 @@ import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.components.ProgressCard;
import org.thoughtcrime.securesms.conversation.colors.ColorizerView;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.scribbles.UriGlideRenderer;
import org.signal.imageeditor.core.renderers.UriGlideRenderer;
import org.thoughtcrime.securesms.util.AsynchronousCallback;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.Projection;

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2026 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.signal.core.util
import android.graphics.Bitmap
import androidx.core.graphics.scale
/**
* Creates a scaled bitmap with the given maximum dimensions while maintaining the original aspect ratio.
*/
fun Bitmap.scaleWithAspectRatio(maxWidth: Int, maxHeight: Int): Bitmap {
if (getWidth() <= maxWidth && getHeight() <= maxHeight) {
return this
}
if (maxWidth <= 0 || maxHeight <= 0) {
return this
}
var newWidth = maxWidth
var newHeight = maxHeight
val widthRatio: Float = getWidth() / maxWidth.toFloat()
val heightRatio: Float = getHeight() / maxHeight.toFloat()
if (widthRatio > heightRatio) {
newHeight = (getHeight() / widthRatio).toInt()
} else {
newWidth = (getWidth() / heightRatio).toInt()
}
return scale(newWidth, newHeight)
}

View File

@@ -50,6 +50,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
<sha256 value="b1fc84725346341c326675860b9097236bd3dfbffdc6e20bfe0717dbf22a0413" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="androidx.activity" name="activity" version="1.2.4">
<artifact name="activity-1.2.4.aar">
<sha256 value="ae8e9c7de57e387d2ad90e73f3a5a5dfd502bd4f034c1dccfdb3506d1d2df81a" origin="Generated by Gradle"/>
</artifact>
<artifact name="activity-1.2.4.module">
<sha256 value="20f5634f76717910e5b4299909d6998a8078f106bdb9e15b2dd75fcfc1bd42b5" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="androidx.activity" name="activity" version="1.6.0">
<artifact name="activity-1.6.0.module">
<md5 value="cfb74f43b3e67840c5b29341c5b477d0" origin="Generated by Gradle"/>
@@ -268,6 +276,9 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
</artifact>
</component>
<component group="androidx.annotation" name="annotation" version="1.3.0">
<artifact name="annotation-1.3.0.jar">
<sha256 value="97dc45afefe3a1e421da42b8b6e9f90491477c45fc6178203e3a5e8a05ee8553" origin="Generated by Gradle"/>
</artifact>
<artifact name="annotation-1.3.0.module">
<md5 value="9b5ed788ed2c3042f1efb2df4b11b346" origin="Generated by Gradle"/>
<sha1 value="6adc685f78686901844153d9d7f41774e649eb4b" origin="Generated by Gradle"/>
@@ -1162,6 +1173,11 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
<sha256 value="77b3ecfd07ce23783d0d4712f6ce3611a5fe54aabaefd9dc07c2dcd903a29160" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="androidx.compose.foundation" name="foundation" version="1.8.1">
<artifact name="foundation-1.8.1.module">
<sha256 value="0ae9b9099979aefafa5d8fd6007f4d795f04847ea5defb664c57c8b4680b50f2" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="androidx.compose.foundation" name="foundation" version="1.9.0">
<artifact name="foundation-1.9.0.module">
<sha256 value="00a1aeb311446fd004f3f66fc32049b53ce6f6b35349385abad3e7b8112060b3" origin="Generated by Gradle"/>
@@ -4155,6 +4171,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
<sha256 value="a14c8b8f2153f128e800fbd266a6beab1c283982a29ec570d2cc05d307d81496" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="androidx.fragment" name="fragment" version="1.3.6">
<artifact name="fragment-1.3.6.aar">
<sha256 value="12f0831b4f08092d5dda272c1923c11a022ff20ceffed3e801751e21bb8d1c1e" origin="Generated by Gradle"/>
</artifact>
<artifact name="fragment-1.3.6.module">
<sha256 value="a140981a3e65f3cab354652682061d23d19b01e00ee712bc38a5e9b0f69eedcf" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="androidx.fragment" name="fragment" version="1.8.5">
<artifact name="fragment-1.8.5.aar">
<md5 value="675a0d0b1d2eca501de49c20fcac99a0" origin="Generated by Gradle"/>
@@ -4624,6 +4648,9 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
</artifact>
</component>
<component group="androidx.lifecycle" name="lifecycle-livedata-core" version="2.3.1">
<artifact name="lifecycle-livedata-core-2.3.1.aar">
<sha256 value="e55d38c372460f0a03997ddc950c67227511340fd74f8634d99d29653cd81ab1" origin="Generated by Gradle"/>
</artifact>
<artifact name="lifecycle-livedata-core-2.3.1.module">
<sha256 value="b1e095d550d39a7d6c815761d6dbe3fd64eb31a39dc28146e78bbf2c01ba8f41" origin="Generated by Gradle"/>
</artifact>
@@ -5049,6 +5076,9 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
</artifact>
</component>
<component group="androidx.lifecycle" name="lifecycle-runtime" version="2.3.1">
<artifact name="lifecycle-runtime-2.3.1.aar">
<sha256 value="dd294f4a689c71ff877fd41f3b67a3a62f7760d44ce420e6130f1fc3569d8f00" origin="Generated by Gradle"/>
</artifact>
<artifact name="lifecycle-runtime-2.3.1.module">
<md5 value="650288b7906ec0f2b9cba2d08dc5783f" origin="Generated by Gradle"/>
<sha1 value="d459c7a0e1758ee24f5dae6386ed9d8b90483c4c" origin="Generated by Gradle"/>
@@ -5662,6 +5692,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
<sha256 value="508bf3284757169fc57f42b84bef0b8538c93af2bd0bec5ba3efe93d45a5bf79" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="androidx.lifecycle" name="lifecycle-viewmodel" version="2.3.1">
<artifact name="lifecycle-viewmodel-2.3.1.aar">
<sha256 value="b6db4c274a12ff85a4747e1e6669c7e98aefa2571ace9d1f1a6fa6be417ce838" origin="Generated by Gradle"/>
</artifact>
<artifact name="lifecycle-viewmodel-2.3.1.module">
<sha256 value="a531853dfe316c90b7466d24be94dbe60a60ef54a52c904c86381986202e51f4" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="androidx.lifecycle" name="lifecycle-viewmodel" version="2.5.1">
<artifact name="lifecycle-viewmodel-2.5.1.module">
<md5 value="bcc8b1b08c59d1a419681807d832a90c" origin="Generated by Gradle"/>
@@ -6179,6 +6217,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
<sha256 value="b18144e91c4780b3b05943256053d7d4dccc45b153066d5f5ffce1839aa0511b" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="androidx.lifecycle" name="lifecycle-viewmodel-savedstate" version="2.3.1">
<artifact name="lifecycle-viewmodel-savedstate-2.3.1.aar">
<sha256 value="97137a8af6a31776a14e4866ab808c7c0a791b484bdbc788bbd83e66407564c0" origin="Generated by Gradle"/>
</artifact>
<artifact name="lifecycle-viewmodel-savedstate-2.3.1.module">
<sha256 value="8083710b758ac096891e91f51d91ee56a445b265d7becf230355377327c0418b" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="androidx.lifecycle" name="lifecycle-viewmodel-savedstate" version="2.6.1">
<artifact name="lifecycle-viewmodel-savedstate-2.6.1.aar">
<md5 value="2ec5a2c5c6114f5882fc80bc7b8cfbea" origin="Generated by Gradle"/>
@@ -6929,6 +6975,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
<sha256 value="2510a5619c37579c9ce1a04574faaf323cd0ffe2fc4e20fa8f8f01e5bb402e83" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="androidx.savedstate" name="savedstate" version="1.1.0">
<artifact name="savedstate-1.1.0.aar">
<sha256 value="d60bbe44c2c08083a17c5dc678a6d6b4d0a2d664858016ab5c049cbea90a63b7" origin="Generated by Gradle"/>
</artifact>
<artifact name="savedstate-1.1.0.module">
<sha256 value="6eea2bc150828c8fcba777e93037038e2ee3ec441c43d6acecf2c5cd9ddc5374" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="androidx.savedstate" name="savedstate" version="1.2.0">
<artifact name="savedstate-1.2.0.module">
<md5 value="f802e52cd475ad80148c42bab34d8ef8" origin="Generated by Gradle"/>

View File

@@ -15,7 +15,7 @@ android {
dependencies {
implementation(project(":core:util"))
implementation(libs.glide.glide)
api(libs.glide.glide)
ksp(libs.glide.ksp)
implementation(platform(libs.androidx.compose.bom))

View File

@@ -8,4 +8,5 @@ android {
dependencies {
implementation(project(":core:util"))
implementation(project(":lib:glide"))
}

View File

@@ -1,4 +1,9 @@
package org.thoughtcrime.securesms.scribbles;
/*
* Copyright 2026 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.signal.imageeditor.core.renderers;
import android.content.Context;
import android.graphics.Bitmap;
@@ -25,6 +30,7 @@ import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.transition.Transition;
import org.signal.core.util.BitmapExtensionsKt;
import org.signal.core.util.logging.Log;
import org.signal.imageeditor.core.Bounds;
import org.signal.imageeditor.core.Renderer;
@@ -33,7 +39,6 @@ import org.signal.imageeditor.core.SelectableRenderer;
import org.signal.imageeditor.core.model.EditorElement;
import org.signal.imageeditor.core.model.EditorModel;
import org.signal.glide.decryptableuri.DecryptableUri;
import org.thoughtcrime.securesms.util.BitmapUtil;
import java.util.concurrent.ExecutionException;
@@ -256,7 +261,7 @@ public final class UriGlideRenderer implements SelectableRenderer {
private static @NonNull Bitmap blur(Bitmap bitmap, Context context, float blurRadius) {
Point previewSize = scaleKeepingAspectRatio(new Point(bitmap.getWidth(), bitmap.getHeight()), PREVIEW_DIMENSION_LIMIT);
Point blurSize = scaleKeepingAspectRatio(new Point(previewSize.x / 2, previewSize.y / 2 ), MAX_BLUR_DIMENSION);
Bitmap small = BitmapUtil.createScaledBitmap(bitmap, blurSize.x, blurSize.y);
Bitmap small = BitmapExtensionsKt.scaleWithAspectRatio(bitmap, blurSize.x, blurSize.y);
Log.d(TAG, "Bitmap: " + bitmap.getWidth() + "x" + bitmap.getHeight() + ", Blur: " + blurSize.x + "x" + blurSize.y);