From 5064fe0899d2a9d35106de6d511b4218c5eb5cc2 Mon Sep 17 00:00:00 2001 From: xinfengkun Date: Thu, 6 Apr 2023 14:31:36 +0800 Subject: [PATCH] =?UTF-8?q?[2.15.0][hmi]=20=E6=B7=BB=E5=8A=A0=E6=B8=85?= =?UTF-8?q?=E6=89=AB=E8=BD=A6=E6=91=84=E5=83=8F=E5=A4=B4View=EF=BC=8C?= =?UTF-8?q?=E5=8D=87=E7=BA=A7glide=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adas/client/ui/BackCameraFloatWindow.java | 5 +- .../client/ui/widget/SweeperVideoView.java | 80 +++++++++ .../image/GlideRoundedCornersTransform.java | 166 ++++++++++++++++++ .../utils/image/ImageLoaderManager.java | 20 --- .../main/res/layout/layout_back_camera.xml | 2 +- config.gradle | 8 +- .../hmi/ui/widget/SweeperVideoView.java | 87 +++++++++ 7 files changed, 341 insertions(+), 27 deletions(-) create mode 100644 app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/widget/SweeperVideoView.java create mode 100644 app_ipc_monitoring/src/main/java/com/zhidao/adas/client/utils/image/GlideRoundedCornersTransform.java create mode 100644 core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SweeperVideoView.java diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/BackCameraFloatWindow.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/BackCameraFloatWindow.java index 8294ce3b40..050aaafe93 100644 --- a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/BackCameraFloatWindow.java +++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/BackCameraFloatWindow.java @@ -13,6 +13,7 @@ import android.view.WindowManager; import android.widget.ImageView; import com.zhidao.adas.client.R; +import com.zhidao.adas.client.ui.widget.SweeperVideoView; import com.zhidao.adas.client.utils.SysBarUtil; import com.zhidao.adas.client.utils.image.ImageLoaderManager; @@ -38,7 +39,7 @@ public class BackCameraFloatWindow implements View.OnTouchListener { private float mDownInScreenY; private float mInScreenX; private float mInScreenY; - private ImageView image_view; + private SweeperVideoView image_view; private final boolean isFullScreen; private final OnBackCameraFloatWindowListener onBackCameraFloatWindowListener; @@ -197,7 +198,7 @@ public class BackCameraFloatWindow implements View.OnTouchListener { protected void handleMessage(Message msg) { switch (msg.what) { case 1: - ImageLoaderManager.loadByteImage(mContext, (byte[]) msg.obj, image_view); + image_view.onSweeperFutianBackCameraVideo((byte[]) msg.obj); break; } } diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/widget/SweeperVideoView.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/widget/SweeperVideoView.java new file mode 100644 index 0000000000..69e1faceac --- /dev/null +++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/widget/SweeperVideoView.java @@ -0,0 +1,80 @@ +package com.zhidao.adas.client.ui.widget; + + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.AppCompatImageView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.Priority; +import com.bumptech.glide.load.engine.DiskCacheStrategy; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.CustomTarget; +import com.bumptech.glide.request.transition.Transition; +import com.zhidao.adas.client.utils.image.GlideRoundedCornersTransform; + +/** + * 清扫车摄像头展示View + */ +public class SweeperVideoView extends AppCompatImageView { + private static final String TAG = SweeperVideoView.class.getSimpleName(); + private final RequestOptions requestOptions = new RequestOptions() + .priority(Priority.HIGH) + .skipMemoryCache(true) + .diskCacheStrategy(DiskCacheStrategy.NONE) + .dontAnimate(); + + public SweeperVideoView(@NonNull Context context) { + super(context); + } + + public SweeperVideoView(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + + public SweeperVideoView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + int i = 0; + + public void onSweeperFutianBackCameraVideo(@NonNull byte[] data) { + i++; + Log.i(TAG, "数据源加载次数=" + i); + Glide.with(SweeperVideoView.this) + .asBitmap() + .load(data) + .placeholder(SweeperVideoView.this.getDrawable()) +// .optionalTransform(new GlideRoundedCornersTransform(50f, GlideRoundedCornersTransform.CornerType.ALL)) + .apply(requestOptions) + .into(target); + + + } + + int j = 0; + private final CustomTarget target = new CustomTarget() { + @Override + public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) { + j++; + Log.i(TAG, "显示回调次数=" + j); + //回调内容 + if (!resource.isRecycled()) { + setImageBitmap(resource); + } else { + Log.i(TAG, "显示回调 Bitmap被回收"); + } + } + + @Override + public void onLoadCleared(@Nullable Drawable placeholder) { + //这个方法在target被回收时调用,如果在除了imageView以外的地方引用了imageView中的bitmap,在这里清除引用以避免崩溃 + } + }; +} diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/utils/image/GlideRoundedCornersTransform.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/utils/image/GlideRoundedCornersTransform.java new file mode 100644 index 0000000000..f9923dd9f8 --- /dev/null +++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/utils/image/GlideRoundedCornersTransform.java @@ -0,0 +1,166 @@ +package com.zhidao.adas.client.utils.image; + +import android.graphics.Bitmap; +import android.graphics.BitmapShader; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.RectF; + +import androidx.annotation.NonNull; + +import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; +import com.bumptech.glide.load.resource.bitmap.CenterCrop; + +import java.security.MessageDigest; + +/** + * Glide加载图片,使图片变成圆角图片工具 + * 基本用法Glide.with(this).load(imgUrl).apply(RequestOptions.bitmapTransform(GlideRoundedCornersTransform(this))).into(imageView) + * 如果想用多个Transform可以使用{@link com.bumptech.glide.load.MultiTransformation} 进行Transform的融合 + * @author tongchenfei + */ +public class GlideRoundedCornersTransform extends CenterCrop { + private float mRadius; + private CornerType mCornerType; + private static final int VERSION = 1; + private static final String ID = "GlideRoundedCornersTransform." + VERSION; + private static final byte[] ID_BYTES = ID.getBytes(CHARSET); + + /** + * 待处理的圆角枚举 + */ + public enum CornerType { + ALL, + TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT, + TOP, BOTTOM, LEFT, RIGHT, + TOP_LEFT_BOTTOM_RIGHT, + TOP_RIGHT_BOTTOM_LEFT, + TOP_LEFT_TOP_RIGHT_BOTTOM_RIGHT, + TOP_RIGHT_BOTTOM_RIGHT_BOTTOM_LEFT, + TOP_LEFT_TOP_RIGHT + } + + public GlideRoundedCornersTransform(float radius, CornerType cornerType) { + super(); + mRadius = radius; + mCornerType = cornerType; + } + + @Override + protected Bitmap transform(@NonNull BitmapPool pool,@NonNull Bitmap toTransform, int outWidth, int outHeight) { + Bitmap transform = super.transform(pool, toTransform, outWidth, outHeight); + return roundCrop(pool, transform); + } + + private Bitmap roundCrop(BitmapPool pool, Bitmap source) { + if (source == null) { + return null; + } + int width = source.getWidth(); + int height = source.getHeight(); + Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888); + + if (result == null) { + result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config + .ARGB_8888); + } + Canvas canvas = new Canvas(result); + Paint paint = new Paint(); + paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader + .TileMode.CLAMP)); + paint.setAntiAlias(true); + + Path path = new Path(); + drawRoundRect(canvas, paint, path, width, height); + + return result; + } + + private void drawRoundRect(Canvas canvas, Paint paint, Path path, int width, int height) { + float[] rids; + switch (mCornerType) { + case ALL: + rids = new float[]{mRadius, mRadius, mRadius, mRadius, mRadius, mRadius, mRadius, mRadius}; + drawPath(rids, canvas, paint, path, width, height); + break; + case TOP_LEFT: + rids = new float[]{mRadius, mRadius, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; + drawPath(rids, canvas, paint, path, width, height); + break; + case TOP_RIGHT: + rids = new float[]{0.0f, 0.0f, mRadius, mRadius, 0.0f, 0.0f, 0.0f, 0.0f}; + drawPath(rids, canvas, paint, path, width, height); + break; + case BOTTOM_RIGHT: + rids = new float[]{0.0f, 0.0f, 0.0f, 0.0f, mRadius, mRadius, 0.0f, 0.0f}; + drawPath(rids, canvas, paint, path, width, height); + break; + case BOTTOM_LEFT: + rids = new float[]{0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, mRadius, mRadius}; + drawPath(rids, canvas, paint, path, width, height); + break; + case TOP: + rids = new float[]{mRadius, mRadius, mRadius, mRadius, 0.0f, 0.0f, 0.0f, 0.0f}; + drawPath(rids, canvas, paint, path, width, height); + break; + case BOTTOM: + rids = new float[]{0.0f, 0.0f, 0.0f, 0.0f, mRadius, mRadius, mRadius, mRadius}; + drawPath(rids, canvas, paint, path, width, height); + break; + case LEFT: + rids = new float[]{mRadius, mRadius, 0.0f, 0.0f, 0.0f, 0.0f, mRadius, mRadius}; + drawPath(rids, canvas, paint, path, width, height); + break; + case RIGHT: + rids = new float[]{0.0f, 0.0f, mRadius, mRadius, mRadius, mRadius, 0.0f, 0.0f}; + drawPath(rids, canvas, paint, path, width, height); + break; + case TOP_LEFT_BOTTOM_RIGHT: + rids = new float[]{mRadius, mRadius, 0.0f, 0.0f, mRadius, mRadius, 0.0f, 0.0f}; + drawPath(rids, canvas, paint, path, width, height); + break; + case TOP_RIGHT_BOTTOM_LEFT: + rids = new float[]{0.0f, 0.0f, mRadius, mRadius, 0.0f, 0.0f, mRadius, mRadius}; + drawPath(rids, canvas, paint, path, width, height); + break; + case TOP_LEFT_TOP_RIGHT_BOTTOM_RIGHT: + rids = new float[]{mRadius, mRadius, mRadius, mRadius, mRadius, mRadius, 0.0f, 0.0f}; + drawPath(rids, canvas, paint, path, width, height); + break; + case TOP_RIGHT_BOTTOM_RIGHT_BOTTOM_LEFT: + rids = new float[]{0.0f, 0.0f, mRadius, mRadius, mRadius, mRadius, mRadius, mRadius}; + drawPath(rids, canvas, paint, path, width, height); + break; + case TOP_LEFT_TOP_RIGHT: + rids = new float[]{mRadius, mRadius, mRadius, mRadius, 0.0f, 0.0f, 0.0f, 0.0f}; + drawPath(rids, canvas, paint, path, width, height); + break; + default: + throw new RuntimeException("RoundedCorners type not belong to CornerType"); + } + } + + /** + * @param rids 圆角的半径,依次为左上角xy半径,右上角,右下角,左下角 + */ + private void drawPath(float[] rids, Canvas canvas, Paint paint, Path path, int width, int height) { + path.addRoundRect(new RectF(0, 0, width, height), rids, Path.Direction.CW); + canvas.drawPath(path, paint); + } + + @Override + public boolean equals(Object o) { + return o instanceof GlideRoundedCornersTransform; + } + + @Override + public int hashCode() { + return ID.hashCode(); + } + + @Override + public void updateDiskCacheKey(MessageDigest messageDigest) { + messageDigest.update(ID_BYTES); + } +} diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/utils/image/ImageLoaderManager.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/utils/image/ImageLoaderManager.java index 34a586ae80..1c07520895 100644 --- a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/utils/image/ImageLoaderManager.java +++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/utils/image/ImageLoaderManager.java @@ -144,26 +144,6 @@ public class ImageLoaderManager { .into(imageView); } - /** - * 加载字节数组 - * - * @param context - * @param data - * @param imageView - */ - public static void loadByteImage(Context context, byte[] data, ImageView imageView) { - RequestOptions requestOptions = new RequestOptions() - .priority(Priority.HIGH) - .diskCacheStrategy(DiskCacheStrategy.ALL) - .centerInside(); - - Glide.with(context) - .load(data) - .apply(requestOptions) - .placeholder(imageView.getDrawable()) - .into(imageView); - } - /** * 加载高斯模糊 * diff --git a/app_ipc_monitoring/src/main/res/layout/layout_back_camera.xml b/app_ipc_monitoring/src/main/res/layout/layout_back_camera.xml index dca285e90e..6926453ac3 100644 --- a/app_ipc_monitoring/src/main/res/layout/layout_back_camera.xml +++ b/app_ipc_monitoring/src/main/res/layout/layout_back_camera.xml @@ -4,7 +4,7 @@ android:layout_height="match_parent" android:background="@color/colorBlue2"> - diff --git a/config.gradle b/config.gradle index 2bd9bebad6..8bf367ddae 100644 --- a/config.gradle +++ b/config.gradle @@ -40,10 +40,10 @@ ext { arouter : "com.alibaba:arouter-api:1.0.12-mogo", aroutercompiler : "com.alibaba:arouter-compiler:1.0.12-mogo", // glide - glide : 'com.github.bumptech.glide:glide:4.8.0', - glideokhttp3 : 'com.github.bumptech.glide:okhttp3-integration:4.8.0', - glideanno : 'com.github.bumptech.glide:annotations:4.8.0', - glidecompiler : 'com.github.bumptech.glide:compiler:4.8.0', + glide : 'com.github.bumptech.glide:glide:4.11.0', + glideokhttp3 : 'com.github.bumptech.glide:okhttp3-integration:4.11.0', + glideanno : 'com.github.bumptech.glide:annotations:4.11.0', + glidecompiler : 'com.github.bumptech.glide:compiler:4.11.0', androidxannotation : "androidx.annotation:annotation:1.2.0", okhttpinterceptor : "com.squareup.okhttp3:logging-interceptor:3.12.0", // fresco diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SweeperVideoView.java b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SweeperVideoView.java new file mode 100644 index 0000000000..ce038d1457 --- /dev/null +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SweeperVideoView.java @@ -0,0 +1,87 @@ +package com.mogo.eagle.core.function.hmi.ui.widget; + + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.AppCompatImageView; + +import com.bumptech.glide.Priority; +import com.bumptech.glide.load.engine.DiskCacheStrategy; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.CustomTarget; +import com.bumptech.glide.request.transition.Transition; +import com.mogo.eagle.core.function.api.autopilot.IMoGoSweeperFutianBackCameraVideoListener; +import com.mogo.eagle.core.function.call.autopilot.CallerSweeperFutianBackCameraVideoListenerManager; +import com.mogo.eagle.core.utilcode.mogo.glide.GlideApp; +import com.mogo.eagle.core.utilcode.util.ThreadUtils; + +/** + * 清扫车摄像头展示View + */ +public class SweeperVideoView extends AppCompatImageView implements IMoGoSweeperFutianBackCameraVideoListener { + private static final String TAG = SweeperVideoView.class.getSimpleName(); + private final RequestOptions requestOptions = new RequestOptions() + .priority(Priority.HIGH) + .skipMemoryCache(true) + .diskCacheStrategy(DiskCacheStrategy.NONE) + .dontAnimate(); + + public SweeperVideoView(@NonNull Context context) { + super(context); + } + + public SweeperVideoView(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + + public SweeperVideoView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + CallerSweeperFutianBackCameraVideoListenerManager.INSTANCE.addListener(TAG, this); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + CallerSweeperFutianBackCameraVideoListenerManager.INSTANCE.removeListener(this); + } + + private final CustomTarget target = new CustomTarget() { + @Override + public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) { + //回调内容 + if (!resource.isRecycled()) { + SweeperVideoView.this.setImageBitmap(resource); + } + } + + @Override + public void onLoadCleared(@Nullable Drawable placeholder) { + //这个方法在target被回收时调用,如果在除了imageView以外的地方引用了imageView中的bitmap,在这里清除引用以避免崩溃 + } + }; + + @Override + public void onSweeperFutianBackCameraVideo(@NonNull byte[] data) { + ThreadUtils.runOnUiThread(new Runnable() { + @Override + public void run() { + GlideApp.with(SweeperVideoView.this) + .asBitmap() + .load(data) + .placeholder(SweeperVideoView.this.getDrawable()) + .apply(requestOptions) + .into(target); + } + }); + } +}