1717import android .view .View ;
1818import androidx .annotation .NonNull ;
1919import androidx .annotation .Nullable ;
20+ import io .flutter .embedding .engine .renderer .FlutterRenderer ;
21+ import io .flutter .embedding .engine .renderer .RenderSurface ;
2022
2123/**
2224 * Paints a Flutter UI provided by an {@link android.media.ImageReader} onto a {@link
3234 */
3335@ SuppressLint ("ViewConstructor" )
3436@ TargetApi (19 )
35- public class FlutterImageView extends View {
37+ public class FlutterImageView extends View implements RenderSurface {
3638 private final ImageReader imageReader ;
3739 @ Nullable private Image nextImage ;
3840 @ Nullable private Image currentImage ;
41+ @ Nullable private Bitmap currentBitmap ;
42+ @ Nullable private FlutterRenderer flutterRenderer ;
3943
4044 /**
4145 * Constructs a {@code FlutterImageView} with an {@link android.media.ImageReader} that provides
@@ -46,6 +50,37 @@ public FlutterImageView(@NonNull Context context, @NonNull ImageReader imageRead
4650 this .imageReader = imageReader ;
4751 }
4852
53+ @ Nullable
54+ @ Override
55+ public FlutterRenderer getAttachedRenderer () {
56+ return flutterRenderer ;
57+ }
58+
59+ /**
60+ * Invoked by the owner of this {@code FlutterImageView} when it wants to begin rendering a
61+ * Flutter UI to this {@code FlutterImageView}.
62+ */
63+ @ Override
64+ public void attachToRenderer (@ NonNull FlutterRenderer flutterRenderer ) {
65+ if (this .flutterRenderer != null ) {
66+ this .flutterRenderer .stopRenderingToSurface ();
67+ }
68+
69+ this .flutterRenderer = flutterRenderer ;
70+ flutterRenderer .startRenderingToSurface (imageReader .getSurface ());
71+ }
72+
73+ /**
74+ * Invoked by the owner of this {@code FlutterTextureView} when it no longer wants to render a
75+ * Flutter UI to this {@code FlutterTextureView}.
76+ */
77+ public void detachFromRenderer () {
78+ if (flutterRenderer != null ) {
79+ flutterRenderer .stopRenderingToSurface ();
80+ flutterRenderer = null ;
81+ }
82+ }
83+
4984 /** Acquires the next image to be drawn to the {@link android.graphics.Canvas}. */
5085 @ TargetApi (19 )
5186 public void acquireLatestImage () {
@@ -56,51 +91,40 @@ public void acquireLatestImage() {
5691 @ Override
5792 protected void onDraw (Canvas canvas ) {
5893 super .onDraw (canvas );
59- if (nextImage == null ) {
60- return ;
61- }
62-
63- if (currentImage != null ) {
64- currentImage .close ();
94+ if (nextImage != null ) {
95+ if (currentImage != null ) {
96+ currentImage .close ();
97+ }
98+ currentImage = nextImage ;
99+ nextImage = null ;
100+ updateCurrentBitmap ();
65101 }
66- currentImage = nextImage ;
67- nextImage = null ;
68102
69- if (android .os .Build .VERSION .SDK_INT >= 29 ) {
70- drawImageBuffer (canvas );
71- return ;
103+ if (currentBitmap != null ) {
104+ canvas .drawBitmap (currentBitmap , 0 , 0 , null );
72105 }
73-
74- drawImagePlane (canvas );
75106 }
76107
77108 @ TargetApi (29 )
78- private void drawImageBuffer (@ NonNull Canvas canvas ) {
79- final HardwareBuffer buffer = currentImage .getHardwareBuffer ();
80-
81- final Bitmap bitmap = Bitmap .wrapHardwareBuffer (buffer , ColorSpace .get (ColorSpace .Named .SRGB ));
82- canvas .drawBitmap (bitmap , 0 , 0 , null );
83- }
84-
85- private void drawImagePlane (@ NonNull Canvas canvas ) {
86- if (currentImage == null ) {
87- return ;
88- }
89-
90- final Plane [] imagePlanes = currentImage .getPlanes ();
91- if (imagePlanes .length != 1 ) {
92- return ;
109+ private void updateCurrentBitmap () {
110+ if (android .os .Build .VERSION .SDK_INT >= 29 ) {
111+ final HardwareBuffer buffer = currentImage .getHardwareBuffer ();
112+ currentBitmap = Bitmap .wrapHardwareBuffer (buffer , ColorSpace .get (ColorSpace .Named .SRGB ));
113+ } else {
114+ final Plane [] imagePlanes = currentImage .getPlanes ();
115+ if (imagePlanes .length != 1 ) {
116+ return ;
117+ }
118+
119+ final Plane imagePlane = imagePlanes [0 ];
120+ final int desiredWidth = imagePlane .getRowStride () / imagePlane .getPixelStride ();
121+ final int desiredHeight = currentImage .getHeight ();
122+
123+ currentBitmap =
124+ android .graphics .Bitmap .createBitmap (
125+ desiredWidth , desiredHeight , android .graphics .Bitmap .Config .ARGB_8888 );
126+
127+ currentBitmap .copyPixelsFromBuffer (imagePlane .getBuffer ());
93128 }
94-
95- final Plane imagePlane = imagePlanes [0 ];
96- final int desiredWidth = imagePlane .getRowStride () / imagePlane .getPixelStride ();
97- final int desiredHeight = currentImage .getHeight ();
98-
99- final Bitmap bitmap =
100- android .graphics .Bitmap .createBitmap (
101- desiredWidth , desiredHeight , android .graphics .Bitmap .Config .ARGB_8888 );
102-
103- bitmap .copyPixelsFromBuffer (imagePlane .getBuffer ());
104- canvas .drawBitmap (bitmap , 0 , 0 , null );
105129 }
106130}
0 commit comments