From a5ee959857ecd2896c398efd0b74639def96aee1 Mon Sep 17 00:00:00 2001 From: soopeach Date: Sun, 3 Sep 2023 01:13:42 +0900 Subject: [PATCH 1/4] =?UTF-8?q?[feat/bitmap=5Fresizing]:=20=EB=B6=88?= =?UTF-8?q?=ED=95=84=EC=9A=94=ED=95=9C=20=EB=A1=9C=EA=B7=B8=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../viewmodel/RegisterRestaurantViewModel.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/presentation/src/main/java/org/gdsc/presentation/view/restaurantregistration/viewmodel/RegisterRestaurantViewModel.kt b/presentation/src/main/java/org/gdsc/presentation/view/restaurantregistration/viewmodel/RegisterRestaurantViewModel.kt index a22a0056..0f8d70ee 100644 --- a/presentation/src/main/java/org/gdsc/presentation/view/restaurantregistration/viewmodel/RegisterRestaurantViewModel.kt +++ b/presentation/src/main/java/org/gdsc/presentation/view/restaurantregistration/viewmodel/RegisterRestaurantViewModel.kt @@ -166,9 +166,7 @@ class RegisterRestaurantViewModel @Inject constructor( _foodCategoryState.value = FoodCategoryItem(FoodCategory.fromName(it.category)) _drinkPossibilityState.value = it.canDrinkLiquor _recommendDrinkTextState.value = it.goWellWithLiquor - _recommendMenuListState.value = it.recommendMenu.split("#").drop(1).apply { - println(" isRecommendMenuFullState 테스트 초기화 : ${this}") - } + _recommendMenuListState.value = it.recommendMenu.split("#").drop(1) _introductionTextState.value = it.introduce _restaurantPlaceName.value = it.name _restaurantLocationId.value = restaurantId.toString() From 7d9f7b803f8a87c61ab9afadd25253f57a0b0c57 Mon Sep 17 00:00:00 2001 From: soopeach Date: Sun, 3 Sep 2023 01:15:39 +0900 Subject: [PATCH 2/4] =?UTF-8?q?[feat/bitmap=5Fresizing]:=20=EC=8B=9D?= =?UTF-8?q?=EB=8B=B9=EB=93=B1=EB=A1=9D=20=EC=8B=9C=20=EC=82=AC=EC=A7=84?= =?UTF-8?q?=EC=9D=98=20=ED=81=AC=EA=B8=B0=EB=A5=BC=20=EC=A1=B0=EC=A0=88?= =?UTF-8?q?=ED=95=98=EC=97=AC=20=EB=B3=B4=EB=82=B4=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gdsc/presentation/utils/BitmapUtils.kt | 93 +++++++++++++++++++ .../RegisterRestaurantFragment.kt | 34 ++++--- 2 files changed, 114 insertions(+), 13 deletions(-) create mode 100644 presentation/src/main/java/org/gdsc/presentation/utils/BitmapUtils.kt diff --git a/presentation/src/main/java/org/gdsc/presentation/utils/BitmapUtils.kt b/presentation/src/main/java/org/gdsc/presentation/utils/BitmapUtils.kt new file mode 100644 index 00000000..cb4f5a31 --- /dev/null +++ b/presentation/src/main/java/org/gdsc/presentation/utils/BitmapUtils.kt @@ -0,0 +1,93 @@ +package org.gdsc.presentation.utils + +import android.content.ContentResolver +import android.content.Context +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.graphics.Matrix +import android.net.Uri +import android.os.Environment +import androidx.exifinterface.media.ExifInterface +import java.io.File +import java.io.FileOutputStream +import java.io.IOException +import java.io.InputStream + +object BitmapUtils { + + fun Bitmap.saveBitmapToFile(context: Context, fileName: String): File { + val directory = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES) + directory?.mkdirs() + val file = File(directory, fileName) + + var outputStream: FileOutputStream? = null + try { + outputStream = FileOutputStream(file) + this.compress(Bitmap.CompressFormat.JPEG, 90, outputStream) + outputStream.flush() + return file + } catch (e: IOException) { + e.printStackTrace() + } finally { + outputStream?.close() + } + + return file + } + + private fun Bitmap.rotateBitmap(angle: Float): Bitmap { + val matrix = Matrix() + matrix.postRotate(angle) + return Bitmap.createBitmap( + this, 0, 0, this.width, this.height, matrix, true + ) + } + + private fun getOrientationOfImage(inputStream: InputStream): Int { + val exif = try { + ExifInterface(inputStream) + } catch (e: IOException) { + e.printStackTrace() + return -1 + } + val orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1) + if (orientation != -1) { + when (orientation) { + ExifInterface.ORIENTATION_ROTATE_90 -> return 90 + ExifInterface.ORIENTATION_ROTATE_180 -> return 180 + ExifInterface.ORIENTATION_ROTATE_270 -> return 270 + } + } + return 0 + } + + fun Uri.getCompressedBitmapFromUri(context: Context): Bitmap? { + val resolver: ContentResolver = context.contentResolver + var inputStream: InputStream? = null + try { + + val options = BitmapFactory.Options().apply { + inSampleSize = 2 + } + + inputStream = resolver.openInputStream(this) + + val bitmap = requireNotNull(BitmapFactory.decodeStream(inputStream, null, options)) + + val orientation = getOrientationOfImage(inputStream!!).toFloat() + + return bitmap.rotateBitmap(orientation) + } catch (e: Exception) { + e.printStackTrace() + } finally { + inputStream?.close() + } + return null + } + +} + + + + + diff --git a/presentation/src/main/java/org/gdsc/presentation/view/restaurantregistration/RegisterRestaurantFragment.kt b/presentation/src/main/java/org/gdsc/presentation/view/restaurantregistration/RegisterRestaurantFragment.kt index f5397fc9..cb689751 100644 --- a/presentation/src/main/java/org/gdsc/presentation/view/restaurantregistration/RegisterRestaurantFragment.kt +++ b/presentation/src/main/java/org/gdsc/presentation/view/restaurantregistration/RegisterRestaurantFragment.kt @@ -25,17 +25,17 @@ import org.gdsc.domain.Empty import org.gdsc.presentation.BaseFragment import org.gdsc.presentation.R import org.gdsc.presentation.databinding.FragmentRegisterRestaurantBinding +import org.gdsc.presentation.utils.BitmapUtils.getCompressedBitmapFromUri +import org.gdsc.presentation.utils.BitmapUtils.saveBitmapToFile import org.gdsc.presentation.utils.addAfterTextChangedListener import org.gdsc.presentation.utils.repeatWhenUiStarted import org.gdsc.presentation.utils.animateShrinkWidth import org.gdsc.presentation.utils.checkMediaPermissions -import org.gdsc.presentation.utils.findPath import org.gdsc.presentation.view.MainActivity import org.gdsc.presentation.view.WebViewActivity import org.gdsc.presentation.view.custom.FoodCategoryBottomSheetDialog import org.gdsc.presentation.view.restaurantregistration.adapter.RegisterRestaurantAdapter import org.gdsc.presentation.view.restaurantregistration.viewmodel.RegisterRestaurantViewModel -import java.io.File @AndroidEntryPoint class RegisterRestaurantFragment : BaseFragment() { @@ -218,20 +218,28 @@ class RegisterRestaurantFragment : BaseFragment() { if (navArgs.targetRestaurantId == -1) { val pictures = mutableListOf() - list.forEach { + list.forEachIndexed { index, sUri -> - val file = File(it.toUri().findPath(requireContext())) + sUri.toUri() + .getCompressedBitmapFromUri(context) + ?.saveBitmapToFile(context, "$index.jpg")?.let { imageFile -> - val requestFile = - RequestBody.create(MediaType.parse("image/png"), file) - val body = - MultipartBody.Part.createFormData( - "pictures", - file.name, - requestFile - ) + val requestFile = + RequestBody.create( + MediaType.parse("image/png"), + imageFile + ) + + val body = + MultipartBody.Part.createFormData( + "pictures", + imageFile.name, + requestFile + ) - pictures.add(body) + pictures.add(body) + + } } From 60765dcc11d15c5a2f78d43aff5657ca46d5856d Mon Sep 17 00:00:00 2001 From: soopeach Date: Tue, 5 Sep 2023 09:09:20 +0900 Subject: [PATCH 3/4] =?UTF-8?q?[feat/bitmap=5Fresizing]:=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=ED=95=84=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=ED=95=A0=20=EB=95=8C=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=ED=81=AC=EA=B8=B0=20=EC=A1=B0=EC=A0=88=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../login/SignUpCompleteFragment.kt | 39 ++++++++----------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/presentation/src/main/java/org/gdsc/presentation/login/SignUpCompleteFragment.kt b/presentation/src/main/java/org/gdsc/presentation/login/SignUpCompleteFragment.kt index 1feb6791..99ea6150 100644 --- a/presentation/src/main/java/org/gdsc/presentation/login/SignUpCompleteFragment.kt +++ b/presentation/src/main/java/org/gdsc/presentation/login/SignUpCompleteFragment.kt @@ -1,40 +1,26 @@ package org.gdsc.presentation.login -import android.Manifest import android.annotation.SuppressLint -import android.content.Context import android.content.Intent -import android.content.pm.PackageManager -import android.net.Uri -import android.os.Build import android.os.Bundle -import android.provider.Settings import android.view.LayoutInflater import android.view.MotionEvent import android.view.View import android.view.ViewGroup -import android.widget.Toast -import androidx.activity.result.contract.ActivityResultContracts import androidx.cardview.widget.CardView -import androidx.core.content.ContextCompat import androidx.core.net.toUri -import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.fragment.app.setFragmentResultListener import androidx.navigation.fragment.findNavController -import androidx.navigation.fragment.navArgs -import com.bumptech.glide.Glide -import com.google.android.material.dialog.MaterialAlertDialogBuilder import okhttp3.MediaType import okhttp3.MultipartBody import okhttp3.RequestBody import org.gdsc.presentation.BaseFragment import org.gdsc.presentation.databinding.FragmentSignUpCompleteBinding +import org.gdsc.presentation.utils.BitmapUtils.getCompressedBitmapFromUri +import org.gdsc.presentation.utils.BitmapUtils.saveBitmapToFile import org.gdsc.presentation.utils.checkMediaPermissions -import org.gdsc.presentation.utils.findPath -import org.gdsc.presentation.utils.showMediaPermissionsDialog import org.gdsc.presentation.view.MainActivity -import java.io.File class SignUpCompleteFragment : BaseFragment() { @@ -79,15 +65,22 @@ class SignUpCompleteFragment : BaseFragment() { binding.nextBtn.setOnClickListener { viewModel.profileImageState.value.let { - if(it.isNullOrEmpty()) + if(it.isEmpty()) viewModel.requestSignUpWithoutImage { moveToMain() } else { - val file = File(it.toUri().findPath(requireContext())) - val requestFile = RequestBody.create(MediaType.parse("image/png"), file) - val body = - MultipartBody.Part.createFormData("profileImg", file.name, requestFile) - viewModel.requestSignUpWithImage(body) { - moveToMain() + val file = it.toUri() + .getCompressedBitmapFromUri(requireContext()) + ?.saveBitmapToFile(requireContext(), "profile.jpg") + + if (file != null) { + val requestFile = RequestBody.create(MediaType.parse("image/png"), file) + val body = + MultipartBody.Part.createFormData("profileImg", file.name, requestFile) + viewModel.requestSignUpWithImage(body) { + moveToMain() + } + } else { + // TODO: Exception Handling } } } From 73ee78cd6d4603a106ead4ffc853c25d88e435d3 Mon Sep 17 00:00:00 2001 From: soopeach Date: Wed, 6 Sep 2023 10:35:29 +0900 Subject: [PATCH 4/4] =?UTF-8?q?[feat/bitmap=5Fresizing]:=20=EB=B9=84?= =?UTF-8?q?=ED=8A=B8=EB=A7=B5=20=EB=A9=94=EB=AA=A8=EB=A6=AC=20=ED=95=A0?= =?UTF-8?q?=EB=8B=B9=20=ED=95=B4=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/org/gdsc/presentation/utils/BitmapUtils.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/presentation/src/main/java/org/gdsc/presentation/utils/BitmapUtils.kt b/presentation/src/main/java/org/gdsc/presentation/utils/BitmapUtils.kt index cb4f5a31..25eaa081 100644 --- a/presentation/src/main/java/org/gdsc/presentation/utils/BitmapUtils.kt +++ b/presentation/src/main/java/org/gdsc/presentation/utils/BitmapUtils.kt @@ -25,6 +25,7 @@ object BitmapUtils { outputStream = FileOutputStream(file) this.compress(Bitmap.CompressFormat.JPEG, 90, outputStream) outputStream.flush() + this.recycle() return file } catch (e: IOException) { e.printStackTrace()