Crop images (#163)
* Beginning of edit photos activity * First batch for edition of photos * EditActivity working properly except flow & save * Added tests * Changed name of tabLayouts back to tabs * Resolved 2 errors from last build * Truly resolved the 2 issues with requireContext/Activity * Made test work with API23 emulator * added 2 tests * Corrected test @Before to have the right button to click on * Added flow to newPost and few tests * Added a test and refactor PhotoEditActivity * Added flow from upload picture, tests doesn't work * Added CropImageActivity from ucrop library, crashes for now * Modified test FiltersIsSwipeableAndClickeable but still doesn't work * Merge with master * rectified test SaveButtonLaunchNewPostActivity * FiltersIsSwipeableAndClickeable test completed * Ready to merge to master * resolved error in merge * Added button save and upload, removed BitmapUtils * Removed unnecessary libraries and imports * Remove dependency on library for permissions * Added crop, rescale of big images to avoid lag, bug fixes * Remove unnessecary imports Co-authored-by: Joachim Dunant <joachim.dunant@epfl.ch> Co-authored-by: Matthieu De Beule <61561059+Wv5twkFEKh54vo4tta9yu7dHa3@users.noreply.github.com>
This commit is contained in:
parent
8fb5074f84
commit
5ac3967400
@ -83,6 +83,7 @@ dependencies {
|
||||
implementation 'androidx.navigation:navigation-ui-ktx:2.2.2'
|
||||
|
||||
implementation 'info.androidhive:imagefilters:1.0.7'
|
||||
implementation 'com.github.yalantis:ucrop:2.2.5-native'
|
||||
|
||||
implementation("com.github.bumptech.glide:glide:4.11.0") {
|
||||
exclude group: "com.android.support"
|
||||
|
@ -108,10 +108,11 @@ class EditPhotoTest {
|
||||
Thread.sleep(1000)
|
||||
Espresso.onView(withId(R.id.recycler_view))
|
||||
.perform(actionOnItemAtPosition<ThumbnailAdapter.MyViewHolder>(5, CustomMatchers.clickChildViewWithId(R.id.thumbnail)))
|
||||
Espresso.onView(withId(R.id.image_preview)).check(matches(isDisplayed()))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun BirghtnessSaturationContrastTest() {
|
||||
fun BrightnessSaturationContrastTest() {
|
||||
Espresso.onView(withId(R.id.tabs)).perform(selectTabAtPosition(1))
|
||||
|
||||
Thread.sleep(1000)
|
||||
@ -143,7 +144,6 @@ class EditPhotoTest {
|
||||
Espresso.onView(withId(R.id.action_save)).perform(click())
|
||||
Espresso.onView(withId(com.google.android.material.R.id.snackbar_text))
|
||||
.check(matches(withText("Image succesfully saved")))
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -153,4 +153,11 @@ class EditPhotoTest {
|
||||
Espresso.onView(withId(R.id.post_creation_picture_frame)).check(matches(isDisplayed()))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun croppingIsPossible() {
|
||||
Espresso.onView(withId(R.id.cropImageButton)).perform(click())
|
||||
Thread.sleep(1000)
|
||||
Espresso.onView(withId(R.id.menu_crop)).perform(click())
|
||||
Espresso.onView(withId(R.id.image_preview)).check(matches(isDisplayed()))
|
||||
}
|
||||
}
|
@ -1,16 +1,28 @@
|
||||
package com.h.pixeldroid
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Bitmap.CompressFormat
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.Point
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.provider.MediaStore
|
||||
import android.util.Log
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.request.RequestOptions
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.h.pixeldroid.adapters.EditPhotoViewPagerAdapter
|
||||
@ -19,12 +31,14 @@ import com.h.pixeldroid.fragments.FilterListFragment
|
||||
import com.h.pixeldroid.interfaces.EditImageFragmentListener
|
||||
import com.h.pixeldroid.interfaces.FilterListFragmentListener
|
||||
import com.h.pixeldroid.utils.NonSwipeableViewPager
|
||||
import com.yalantis.ucrop.UCrop
|
||||
import com.zomato.photofilters.imageprocessors.Filter
|
||||
import com.zomato.photofilters.imageprocessors.subfilters.BrightnessSubFilter
|
||||
import com.zomato.photofilters.imageprocessors.subfilters.ContrastSubFilter
|
||||
import com.zomato.photofilters.imageprocessors.subfilters.SaturationSubfilter
|
||||
import kotlinx.android.synthetic.main.activity_photo_edit.*
|
||||
import kotlinx.android.synthetic.main.content_photo_edit.*
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.text.SimpleDateFormat
|
||||
@ -40,12 +54,19 @@ private val REQUIRED_PERMISSIONS = arrayOf(android.Manifest.permission.READ_EXTE
|
||||
|
||||
class PhotoEditActivity : AppCompatActivity(), FilterListFragmentListener, EditImageFragmentListener {
|
||||
|
||||
val BITMAP_CONFIG = Bitmap.Config.ARGB_8888
|
||||
private val BITMAP_CONFIG = Bitmap.Config.ARGB_8888
|
||||
private val BRIGHTNESS_START = 0
|
||||
private val SATURATION_START = 1.0f
|
||||
private val CONTRAST_START = 1.0f
|
||||
|
||||
private var originalImage: Bitmap? = null
|
||||
private var compressedImage: Bitmap? = null
|
||||
private var compressedOriginalImage: Bitmap? = null
|
||||
private lateinit var filteredImage: Bitmap
|
||||
private lateinit var finalImage: Bitmap
|
||||
|
||||
private var actualFilter: Filter? = null
|
||||
|
||||
private lateinit var filterListFragment: FilterListFragment
|
||||
private lateinit var editImageFragment: EditImageFragment
|
||||
|
||||
@ -54,11 +75,12 @@ class PhotoEditActivity : AppCompatActivity(), FilterListFragmentListener, EditI
|
||||
lateinit var viewPager: NonSwipeableViewPager
|
||||
lateinit var tabLayout: TabLayout
|
||||
|
||||
private var brightnessFinal = 0
|
||||
private var saturationFinal = 1.0f
|
||||
private var contrastFinal = 1.0f
|
||||
private var brightnessFinal = BRIGHTNESS_START
|
||||
private var saturationFinal = SATURATION_START
|
||||
private var contrastFinal = CONTRAST_START
|
||||
|
||||
private var resultUri: Uri? = null
|
||||
private var imageUri: Uri? = null
|
||||
private var cropUri: Uri? = null
|
||||
|
||||
object URI {var picture_uri: Uri? = null}
|
||||
|
||||
@ -70,39 +92,48 @@ class PhotoEditActivity : AppCompatActivity(), FilterListFragmentListener, EditI
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_photo_edit)
|
||||
|
||||
URI.picture_uri = intent.getParcelableExtra("uri")
|
||||
|
||||
resultUri = URI.picture_uri
|
||||
|
||||
setSupportActionBar(toolbar)
|
||||
supportActionBar!!.title = "Edit"
|
||||
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
|
||||
supportActionBar!!.setHomeButtonEnabled(true)
|
||||
|
||||
cropUri = intent.getParcelableExtra("uri")
|
||||
|
||||
loadImage()
|
||||
val file = File.createTempFile("temp_compressed_img", ".png", cacheDir)
|
||||
file.writeBitmap(compressedImage!!)
|
||||
URI.picture_uri = Uri.fromFile(file)
|
||||
|
||||
viewPager = findViewById(R.id.viewPager)
|
||||
tabLayout = findViewById(R.id.tabs)
|
||||
setupViewPager(viewPager)
|
||||
tabLayout.setupWithViewPager(viewPager)
|
||||
outputDirectory = getOutputDirectory()
|
||||
|
||||
val cropButton: FloatingActionButton = findViewById(R.id.cropImageButton)
|
||||
// set on-click listener
|
||||
cropButton.setOnClickListener {
|
||||
startCrop()
|
||||
}
|
||||
}
|
||||
|
||||
/** Use external media if it is available, our app's file directory otherwise */
|
||||
private fun getOutputDirectory(): File {
|
||||
val appContext = applicationContext
|
||||
val mediaDir = externalMediaDirs.firstOrNull()?.let {
|
||||
File(it, appContext.resources.getString(R.string.app_name)).apply { mkdirs() } }
|
||||
return if (mediaDir != null && mediaDir.exists())
|
||||
mediaDir else appContext.filesDir
|
||||
}
|
||||
|
||||
//<editor-fold desc="ON LAUNCH">
|
||||
private fun loadImage() {
|
||||
originalImage = MediaStore.Images.Media.getBitmap(contentResolver, URI.picture_uri)
|
||||
originalImage = MediaStore.Images.Media.getBitmap(contentResolver, cropUri)
|
||||
compressedImage = resizeImage(originalImage!!.copy(BITMAP_CONFIG, true))
|
||||
compressedOriginalImage = compressedImage!!.copy(BITMAP_CONFIG, true)
|
||||
filteredImage = compressedImage!!.copy(BITMAP_CONFIG, true)
|
||||
image_preview.setImageBitmap(compressedImage)
|
||||
}
|
||||
|
||||
filteredImage = originalImage!!.copy(BITMAP_CONFIG, true)
|
||||
finalImage = originalImage!!.copy(BITMAP_CONFIG, true)
|
||||
image_preview.setImageBitmap(originalImage)
|
||||
private fun resizeImage(image: Bitmap): Bitmap {
|
||||
val display = windowManager.defaultDisplay
|
||||
val size = Point()
|
||||
display.getSize(size)
|
||||
|
||||
val newY = size.y * 0.7
|
||||
val scale = newY / image.height
|
||||
return Bitmap.createScaledBitmap(image, (image.width * scale).toInt(), newY.toInt(), true)
|
||||
}
|
||||
|
||||
private fun setupViewPager(viewPager: NonSwipeableViewPager?) {
|
||||
@ -142,6 +173,133 @@ class PhotoEditActivity : AppCompatActivity(), FilterListFragmentListener, EditI
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
//</editor-fold>
|
||||
//<editor-fold desc="FILTERS">
|
||||
|
||||
override fun onFilterSelected(filter: Filter) {
|
||||
resetControls()
|
||||
filteredImage = compressedOriginalImage!!.copy(BITMAP_CONFIG, true)
|
||||
image_preview.setImageBitmap(filter.processFilter(filteredImage))
|
||||
compressedImage = filteredImage.copy(BITMAP_CONFIG, true)
|
||||
actualFilter = filter
|
||||
}
|
||||
|
||||
private fun resetControls() {
|
||||
editImageFragment.resetControl()
|
||||
|
||||
brightnessFinal = BRIGHTNESS_START
|
||||
saturationFinal = SATURATION_START
|
||||
contrastFinal = CONTRAST_START
|
||||
}
|
||||
|
||||
//</editor-fold>
|
||||
//<editor-fold desc="EDITS">
|
||||
|
||||
private fun applyFilterAndShowImage(filter: Filter, image: Bitmap?) {
|
||||
image_preview.setImageBitmap(filter.processFilter(image!!.copy(BITMAP_CONFIG, true)))
|
||||
}
|
||||
|
||||
override fun onBrightnessChange(brightness: Int) {
|
||||
brightnessFinal = brightness
|
||||
val myFilter = Filter()
|
||||
myFilter.addSubFilter(BrightnessSubFilter(brightness))
|
||||
applyFilterAndShowImage(myFilter, filteredImage)
|
||||
}
|
||||
|
||||
override fun onSaturationChange(saturation: Float) {
|
||||
saturationFinal = saturation
|
||||
val myFilter = Filter()
|
||||
myFilter.addSubFilter(SaturationSubfilter(saturation))
|
||||
applyFilterAndShowImage(myFilter, filteredImage)
|
||||
}
|
||||
|
||||
override fun onContrastChange(contrast: Float) {
|
||||
contrastFinal = contrast
|
||||
val myFilter = Filter()
|
||||
myFilter.addSubFilter(ContrastSubFilter(contrast))
|
||||
applyFilterAndShowImage(myFilter, filteredImage)
|
||||
}
|
||||
|
||||
private fun addEditFilters(filter: Filter, br: Int, sa: Float, co: Float): Filter {
|
||||
filter.addSubFilter(BrightnessSubFilter(br))
|
||||
filter.addSubFilter(ContrastSubFilter(co))
|
||||
filter.addSubFilter(SaturationSubfilter(sa))
|
||||
|
||||
return filter
|
||||
}
|
||||
|
||||
override fun onEditStarted() {
|
||||
}
|
||||
|
||||
override fun onEditCompleted() {
|
||||
val bitmap = filteredImage.copy(BITMAP_CONFIG, true)
|
||||
val myFilter = Filter()
|
||||
addEditFilters(myFilter, brightnessFinal, saturationFinal, contrastFinal)
|
||||
|
||||
compressedImage = myFilter.processFilter(bitmap)
|
||||
}
|
||||
|
||||
//</editor-fold>
|
||||
//<editor-fold desc="CROPPING">
|
||||
|
||||
private fun startCrop() {
|
||||
applyFinalFilters(MediaStore.Images.Media.getBitmap(contentResolver, cropUri))
|
||||
val file = File.createTempFile("temp_crop_img", ".png", cacheDir)
|
||||
file.writeBitmap(finalImage)
|
||||
|
||||
val uCrop: UCrop = UCrop.of(Uri.fromFile(file), URI.picture_uri!!)
|
||||
uCrop.start(this)
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if(resultCode == Activity.RESULT_OK) {
|
||||
imageUri = data!!.data
|
||||
|
||||
if (requestCode == UCrop.RESULT_ERROR) {
|
||||
handleCropError(data)
|
||||
} else {
|
||||
handleCropResult(data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun resetFilteredImage(){
|
||||
val newBr = if(brightnessFinal != 0) BRIGHTNESS_START/brightnessFinal else 0
|
||||
val newSa = if(saturationFinal != 0.0f) SATURATION_START/saturationFinal else 0.0f
|
||||
val newCo = if(contrastFinal != 0.0f) CONTRAST_START/contrastFinal else 0.0f
|
||||
val myFilter = addEditFilters(Filter(), newBr, newSa, newCo)
|
||||
|
||||
filteredImage = myFilter.processFilter(filteredImage)
|
||||
}
|
||||
|
||||
private fun handleCropResult(data: Intent?) {
|
||||
val resultCrop: Uri? = UCrop.getOutput(data!!)
|
||||
if(resultCrop != null) {
|
||||
image_preview.setImageURI(resultCrop)
|
||||
|
||||
val bitmap = (image_preview.drawable as BitmapDrawable).bitmap
|
||||
originalImage = bitmap.copy(Bitmap.Config.ARGB_8888, true)
|
||||
compressedImage = resizeImage(originalImage!!.copy(BITMAP_CONFIG, true))
|
||||
compressedOriginalImage = compressedImage!!.copy(BITMAP_CONFIG, true)
|
||||
filteredImage = compressedImage!!.copy(BITMAP_CONFIG, true)
|
||||
resetFilteredImage()
|
||||
} else {
|
||||
Toast.makeText(this, "Cannot retrieve image", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleCropError(data: Intent?) {
|
||||
val resultError = UCrop.getError(data!!)
|
||||
if(resultError != null) {
|
||||
Toast.makeText(this, "" + resultError, Toast.LENGTH_SHORT).show()
|
||||
} else {
|
||||
Toast.makeText(this, "Unexpected Error", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
|
||||
//</editor-fold>
|
||||
//<editor-fold desc="FLOW">
|
||||
override fun onRequestPermissionsResult(
|
||||
requestCode: Int,
|
||||
permissions: Array<out String>,
|
||||
@ -160,10 +318,17 @@ class PhotoEditActivity : AppCompatActivity(), FilterListFragmentListener, EditI
|
||||
}
|
||||
}
|
||||
|
||||
private fun applyFinalFilters(image: Bitmap?) {
|
||||
var editFilter = Filter()
|
||||
editFilter = addEditFilters(editFilter, brightnessFinal, saturationFinal, contrastFinal)
|
||||
|
||||
finalImage = editFilter.processFilter(image!!.copy(BITMAP_CONFIG, true))
|
||||
if (actualFilter!=null) finalImage = actualFilter!!.processFilter(finalImage)
|
||||
}
|
||||
|
||||
private fun uploadImage(file: File) {
|
||||
val intent = Intent (applicationContext, PostCreationActivity::class.java)
|
||||
intent.putExtra("picture_uri", Uri.fromFile(file))
|
||||
//file.delete()
|
||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
applicationContext!!.startActivity(intent)
|
||||
}
|
||||
@ -189,6 +354,15 @@ class PhotoEditActivity : AppCompatActivity(), FilterListFragmentListener, EditI
|
||||
applicationContext, it) == PackageManager.PERMISSION_GRANTED
|
||||
}
|
||||
|
||||
/** Use external media if it is available, our app's file directory otherwise */
|
||||
private fun getOutputDirectory(): File {
|
||||
val appContext = applicationContext
|
||||
val mediaDir = externalMediaDirs.firstOrNull()?.let {
|
||||
File(it, appContext.resources.getString(R.string.app_name)).apply { mkdirs() } }
|
||||
return if (mediaDir != null && mediaDir.exists())
|
||||
mediaDir else appContext.filesDir
|
||||
}
|
||||
|
||||
private fun File.writeBitmap(bitmap: Bitmap) {
|
||||
outputStream().use { out ->
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 85, out)
|
||||
@ -197,15 +371,17 @@ class PhotoEditActivity : AppCompatActivity(), FilterListFragmentListener, EditI
|
||||
}
|
||||
|
||||
private fun permissionsGrantedToSave(save: Boolean) {
|
||||
val file = if(!save){
|
||||
//put picture in cache
|
||||
File.createTempFile("temp_img", ".png", cacheDir)
|
||||
} else{
|
||||
// Save the picture (quality is ignored for PNG)
|
||||
File(outputDirectory, SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS", Locale.US)
|
||||
val file =
|
||||
if(!save){
|
||||
//put picture in cache
|
||||
File.createTempFile("temp_edit_img", ".png", cacheDir)
|
||||
} else{
|
||||
// Save the picture (quality is ignored for PNG)
|
||||
File(outputDirectory, SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS", Locale.US)
|
||||
.format(System.currentTimeMillis()) + ".png")
|
||||
}
|
||||
}
|
||||
try {
|
||||
applyFinalFilters(originalImage)
|
||||
file.writeBitmap(finalImage)
|
||||
} catch (e: IOException) {
|
||||
Snackbar.make(coordinator_edit, "Unable to save image", Snackbar.LENGTH_LONG).show()
|
||||
@ -217,54 +393,5 @@ class PhotoEditActivity : AppCompatActivity(), FilterListFragmentListener, EditI
|
||||
Snackbar.make(coordinator_edit, "Image succesfully saved", Snackbar.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFilterSelected(filter: Filter) {
|
||||
resetControls()
|
||||
filteredImage = originalImage!!.copy(BITMAP_CONFIG, true)
|
||||
image_preview.setImageBitmap(filter.processFilter(filteredImage))
|
||||
finalImage = filteredImage.copy(BITMAP_CONFIG, true)
|
||||
}
|
||||
|
||||
private fun resetControls() {
|
||||
editImageFragment.resetControl()
|
||||
|
||||
brightnessFinal = 0
|
||||
saturationFinal = 1.0f
|
||||
contrastFinal = 1.0f
|
||||
}
|
||||
|
||||
override fun onBrightnessChange(brightness: Int) {
|
||||
brightnessFinal = brightness
|
||||
val myFilter = Filter()
|
||||
myFilter.addSubFilter(BrightnessSubFilter(brightness))
|
||||
image_preview.setImageBitmap(myFilter.processFilter(finalImage.copy(BITMAP_CONFIG, true)))
|
||||
}
|
||||
|
||||
override fun onSaturationChange(saturation: Float) {
|
||||
saturationFinal = saturation
|
||||
val myFilter = Filter()
|
||||
myFilter.addSubFilter(SaturationSubfilter(saturation))
|
||||
image_preview.setImageBitmap(myFilter.processFilter(finalImage.copy(BITMAP_CONFIG, true)))
|
||||
}
|
||||
|
||||
override fun onContrastChange(contrast: Float) {
|
||||
contrastFinal = contrast
|
||||
val myFilter = Filter()
|
||||
myFilter.addSubFilter(ContrastSubFilter(contrast))
|
||||
image_preview.setImageBitmap(myFilter.processFilter(finalImage.copy(BITMAP_CONFIG, true)))
|
||||
}
|
||||
|
||||
override fun onEditStarted() {
|
||||
|
||||
}
|
||||
|
||||
override fun onEditCompleted() {
|
||||
val bitmap = filteredImage.copy(BITMAP_CONFIG, true)
|
||||
val myFilter = Filter()
|
||||
myFilter.addSubFilter(ContrastSubFilter(contrastFinal))
|
||||
myFilter.addSubFilter(SaturationSubfilter(saturationFinal))
|
||||
myFilter.addSubFilter(BrightnessSubFilter(brightnessFinal))
|
||||
|
||||
finalImage = myFilter.processFilter(bitmap)
|
||||
}
|
||||
//</editor-fold>
|
||||
}
|
||||
|
@ -17,9 +17,12 @@ class EditImageFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
|
||||
private lateinit var seekbarSaturation: SeekBar
|
||||
private lateinit var seekbarContrast: SeekBar
|
||||
|
||||
private var BRIGHTNESS_START = 100
|
||||
private var SATURATION_START = 0
|
||||
private var CONTRAST_START = 10
|
||||
private var BRIGHTNESS_MAX = 200
|
||||
private var SATURATION_MAX = 20
|
||||
private var CONTRAST_MAX= 30
|
||||
private var BRIGHTNESS_START = BRIGHTNESS_MAX/2
|
||||
private var SATURATION_START = SATURATION_MAX/2
|
||||
private var CONTRAST_START = CONTRAST_MAX/2
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
@ -32,13 +35,13 @@ class EditImageFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
|
||||
seekbarSaturation = view.findViewById(R.id.seekbar_saturation)
|
||||
seekbarContrast = view.findViewById(R.id.seekbar_contrast)
|
||||
|
||||
seekbarBrightness.max = 200
|
||||
seekbarBrightness.max = BRIGHTNESS_MAX
|
||||
seekbarBrightness.progress = BRIGHTNESS_START
|
||||
|
||||
seekbarContrast.max = 20
|
||||
seekbarContrast.max = CONTRAST_MAX
|
||||
seekbarContrast.progress = CONTRAST_START
|
||||
|
||||
seekbarSaturation.max = 30
|
||||
seekbarSaturation.max = SATURATION_MAX
|
||||
seekbarSaturation.progress = SATURATION_START
|
||||
|
||||
seekbarBrightness.setOnSeekBarChangeListener(this)
|
||||
|
@ -11,15 +11,15 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="@style/AppTheme.AppBarOverlay">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay" />
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<include layout="@layout/content_photo_edit" />
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="@color/colorPrimary"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay"/>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
@ -13,9 +13,17 @@
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image_preview"
|
||||
android:scaleType="centerInside"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="400dp"/>
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight=".70"
|
||||
android:scaleType="centerInside" />
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/cropImageButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/ic_crop_black_24dp" />
|
||||
|
||||
<com.h.pixeldroid.utils.NonSwipeableViewPager
|
||||
android:id="@+id/viewPager"
|
||||
@ -23,7 +31,8 @@
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
android:layout_below="@+id/image_preview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="80dp" />
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight=".22" />
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/tabs"
|
||||
@ -31,6 +40,7 @@
|
||||
app:tabMode="fixed"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight=".08"/>
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
@ -12,8 +12,7 @@
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="10dp"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
@ -31,8 +30,8 @@
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="10dp"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:paddingTop="8dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
@ -51,8 +50,7 @@
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="10dp"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingTop="8dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user