1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.camera.core; 18 19 import static androidx.camera.core.internal.utils.ImageUtil.createBitmapFromImageProxy; 20 21 import android.annotation.SuppressLint; 22 import android.graphics.Bitmap; 23 import android.graphics.ImageFormat; 24 import android.graphics.PixelFormat; 25 import android.graphics.Rect; 26 import android.media.Image; 27 28 import org.jspecify.annotations.NonNull; 29 import org.jspecify.annotations.Nullable; 30 31 import java.nio.ByteBuffer; 32 33 /** An image proxy which has a similar interface as {@link android.media.Image}. */ 34 public interface ImageProxy extends AutoCloseable { 35 /** 36 * Closes the underlying {@link android.media.Image}. 37 * 38 * @see android.media.Image#close() 39 */ 40 @Override close()41 void close(); 42 43 /** 44 * Returns the crop rectangle. 45 * 46 * @see android.media.Image#getCropRect() 47 */ getCropRect()48 @NonNull Rect getCropRect(); 49 50 /** 51 * Sets the crop rectangle. 52 * 53 * @see android.media.Image#setCropRect(Rect) 54 */ setCropRect(@ullable Rect rect)55 void setCropRect(@Nullable Rect rect); 56 57 /** 58 * Returns the image format. 59 * 60 * <p> The image format can be one of the {@link ImageFormat} or 61 * {@link PixelFormat} constants. 62 * 63 * @see android.media.Image#getFormat() 64 */ getFormat()65 int getFormat(); 66 67 /** 68 * Returns the image height. 69 * 70 * @see android.media.Image#getHeight() 71 */ getHeight()72 int getHeight(); 73 74 /** 75 * Returns the image width. 76 * 77 * @see android.media.Image#getWidth() 78 */ getWidth()79 int getWidth(); 80 81 /** 82 * Returns the array of planes. 83 * 84 * @see android.media.Image#getPlanes() 85 */ 86 @SuppressLint("ArrayReturn") getPlanes()87 PlaneProxy @NonNull [] getPlanes(); 88 89 /** A plane proxy which has an analogous interface as {@link android.media.Image.Plane}. */ 90 interface PlaneProxy { 91 /** 92 * Returns the row stride. 93 * 94 * @see android.media.Image.Plane#getRowStride() 95 */ getRowStride()96 int getRowStride(); 97 98 /** 99 * Returns the pixel stride. 100 * 101 * @see android.media.Image.Plane#getPixelStride() 102 */ getPixelStride()103 int getPixelStride(); 104 105 /** 106 * Returns the pixels buffer. 107 * 108 * @see android.media.Image.Plane#getBuffer() 109 */ getBuffer()110 @NonNull ByteBuffer getBuffer(); 111 } 112 113 /** Returns the {@link ImageInfo}. */ getImageInfo()114 @NonNull ImageInfo getImageInfo(); 115 116 /** 117 * Returns the android {@link Image}. 118 * 119 * <p>If the ImageProxy is a wrapper for an android {@link Image}, it will return the 120 * {@link Image}. It is possible for an ImageProxy to wrap something that isn't an 121 * {@link Image}. If that's the case then it will return null. 122 * 123 * <p>The returned image should not be closed by the application. Instead it should be closed by 124 * the ImageProxy, which happens, for example, on return from the {@link ImageAnalysis.Analyzer} 125 * function. Destroying the {@link ImageAnalysis} will close the underlying 126 * {@link android.media.ImageReader}. So an {@link Image} obtained with this method will behave 127 * as such. 128 * 129 * @return the android image. 130 * @see android.media.Image#close() 131 */ 132 @ExperimentalGetImage getImage()133 @Nullable Image getImage(); 134 135 /** 136 * Converts {@link ImageProxy} to {@link Bitmap}. 137 * 138 * <p>The supported {@link ImageProxy} format is {@link ImageFormat#YUV_420_888}, 139 * {@link ImageFormat#JPEG} or {@link PixelFormat#RGBA_8888}. If format is invalid, an 140 * {@link IllegalArgumentException} will be thrown. If the conversion to bimap failed, an 141 * {@link UnsupportedOperationException} will be thrown. 142 * 143 * @return {@link Bitmap} instance. 144 */ toBitmap()145 default @NonNull Bitmap toBitmap() { 146 return createBitmapFromImageProxy(this); 147 } 148 } 149