1 /* <lambda>null2 * Copyright 2021 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.integration.extensions.validation 18 19 import android.app.Activity 20 import android.content.ContentResolver 21 import android.graphics.Bitmap 22 import android.graphics.BitmapFactory 23 import android.graphics.Matrix 24 import android.net.Uri 25 import android.os.Bundle 26 import android.view.LayoutInflater 27 import android.view.MotionEvent 28 import android.view.ScaleGestureDetector 29 import android.view.View 30 import android.view.ViewGroup 31 import android.widget.ImageView 32 import androidx.camera.integration.extensions.R 33 import androidx.fragment.app.Fragment 34 import androidx.viewpager2.widget.ViewPager2 35 36 /** Fragment used for each individual page showing a photo inside [ImageValidationActivity]. */ 37 class PhotoFragment constructor() : Fragment() { 38 private lateinit var imageUri: Uri 39 private var rotationDegrees: Int = 0 40 private var scaleGestureListener: ScaleGestureDetector.SimpleOnScaleGestureListener? = null 41 42 /** 43 * Fragment used for each individual page showing a photo inside [ImageValidationActivity] 44 * 45 * @param imageUri The image uri to be displayed in this photo fragment 46 * @param rotationDegrees The rotation degrees to rotate the image to the upright direction 47 * @param scaleGestureListener The scale gesture listener which allow the caller activity to 48 * receive the scale events to switch to another photo view which supports the translation 49 * function in the X direction. It is because this fragment will be put inside a [ViewPager2] 50 * and it will eat the X direction movement events for the [ViewPager2]'s page switch 51 * function. But we'll need the translation function in X direction after the photo is zoomed 52 * in. 53 */ 54 constructor( 55 imageUri: Uri, 56 rotationDegrees: Int, 57 scaleGestureListener: ScaleGestureDetector.SimpleOnScaleGestureListener? 58 ) : this() { 59 this.imageUri = imageUri 60 this.rotationDegrees = rotationDegrees 61 this.scaleGestureListener = scaleGestureListener 62 } 63 64 override fun onCreateView( 65 inflater: LayoutInflater, 66 container: ViewGroup?, 67 savedInstanceState: Bundle? 68 ): View = inflater.inflate(R.layout.single_photo_viewer, container, false) 69 70 private lateinit var photoViewer: ImageView 71 72 override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 73 super.onViewCreated(view, savedInstanceState) 74 75 if (!::imageUri.isInitialized) { 76 return 77 } 78 79 photoViewer = view.findViewById(R.id.imageView) 80 photoViewer.setImageBitmap( 81 decodeImageToBitmap( 82 (requireActivity() as Activity).contentResolver, 83 imageUri, 84 rotationDegrees 85 ) 86 ) 87 88 setPhotoViewerScaleGestureListener() 89 } 90 91 private fun setPhotoViewerScaleGestureListener() { 92 scaleGestureListener?.let { 93 val scaleDetector = ScaleGestureDetector(requireContext(), scaleGestureListener!!) 94 photoViewer.setOnTouchListener { _, e: MotionEvent -> scaleDetector.onTouchEvent(e) } 95 } 96 } 97 98 companion object { 99 fun decodeImageToBitmap( 100 contentResolver: ContentResolver, 101 imageUri: Uri, 102 rotationDegrees: Int 103 ): Bitmap { 104 val parcelFileDescriptor = contentResolver.openFileDescriptor(imageUri, "r") 105 val bitmap = BitmapFactory.decodeFileDescriptor(parcelFileDescriptor?.fileDescriptor) 106 parcelFileDescriptor?.close() 107 108 // Rotates the bitmap to the correct orientation 109 val matrix = Matrix() 110 matrix.postRotate(rotationDegrees.toFloat()) 111 return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true) 112 } 113 } 114 } 115