我想在不使用任何库的情况下裁剪图像。
我正在参考https://stackoverflow.com/a/6909144的内容,并尝试更改该值,但找不到解决方法
Bitmap bitmap = BitmapUtil.getBitmap(path);
Log.d(TAG,"bitmap width : "+bitmap.getWidth()+" height: "+bitmap.getHeight());
if (bitmap.getWidth() >= bitmap.getHeight()){
Toast.makeText(this,"Height Greater",Toast.LENGTH_SHORT).show();
Log.d(TAG,"Greater : Height");
textView.setText("Height Greater");
bitmap = Bitmap.createBitmap(
bitmap,
bitmap.getWidth()/2 - bitmap.getHeight()/2,
0,
bitmap.getHeight(),
bitmap.getHeight()
);
}else{
Toast.makeText(this,"Width Greater",Toast.LENGTH_SHORT).show();
Log.d(TAG,"Greater : Width");
textView.setText("Width Greater");
bitmap = Bitmap.createBitmap(
bitmap,
0,
bitmap.getHeight()/2 - bitmap.getWidth()/2,
bitmap.getWidth(),
bitmap.getWidth()
);
}
我想要矩形内的裁剪位图图像。
答案 0 :(得分:0)
要有效地创建位图,请尝试
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import java.io.ByteArrayOutputStream
/**
*
* ImageScalingUtils responsible for compressing the bitmap efficiently
*/
object ImageScalingUtils {
/**
* Utility function for decoding an image resource. The decoded bitmap will
* be optimized for further scaling to the requested destination dimensions
* and scaling logic.
*
* @param dstWidth Width of destination area
* @param dstHeight Height of destination area
* @param scalingLogic Logic to use to avoid image stretching
* @return Decoded bitmap
*/
fun decodeBitmap(bm: Bitmap, dstWidth: Int, dstHeight: Int,
scalingLogic: ScalingLogic): Bitmap {
val stream = ByteArrayOutputStream()
bm.compress(Bitmap.CompressFormat.PNG, 100, stream)
val byteArray = stream.toByteArray()
val options = BitmapFactory.Options()
options.inJustDecodeBounds = true
BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size, options)
options.inJustDecodeBounds = false
options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth,
dstHeight, scalingLogic)
return BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size, options)
}
/**
* ScalingLogic defines how scaling should be carried out if source and
* destination image has different aspect ratio.
*
* CROP: Scales the image the minimum amount while making sure that at least
* one of the two dimensions fit inside the requested destination area.
* Parts of the source image will be cropped to realize this.
*
* FIT: Scales the image the minimum amount while making sure both
* dimensions fit inside the requested destination area. The resulting
* destination dimensions might be adjusted to a smaller size than
* requested.
*/
enum class ScalingLogic {
CROP, FIT
}
/**
* Calculate optimal down-sampling factor given the dimensions of a source
* image, the dimensions of a destination area and a scaling logic.
*
* @param srcWidth Width of source image
* @param srcHeight Height of source image
* @param dstWidth Width of destination area
* @param dstHeight Height of destination area
* @param scalingLogic Logic to use to avoid image stretching
* @return Optimal down scaling sample size for decoding
*/
private fun calculateSampleSize(srcWidth: Int, srcHeight: Int, dstWidth: Int, dstHeight: Int,
scalingLogic: ScalingLogic): Int {
if (scalingLogic == ScalingLogic.FIT) {
val srcAspect = srcWidth.toFloat() / srcHeight.toFloat()
val dstAspect = dstWidth.toFloat() / dstHeight.toFloat()
return if (srcAspect > dstAspect) {
srcWidth / dstWidth
} else {
srcHeight / dstHeight
}
} else {
val srcAspect = srcWidth.toFloat() / srcHeight.toFloat()
val dstAspect = dstWidth.toFloat() / dstHeight.toFloat()
return if (srcAspect > dstAspect) {
srcHeight / dstHeight
} else {
srcWidth / dstWidth
}
}
}
}
可缩放图片类来缩放图片
import android.content.ContentResolver
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Matrix
import android.graphics.RectF
import android.net.Uri
import androidx.exifinterface.media.ExifInterface
import java.io.FileNotFoundException
import java.io.IOException
import java.io.InvalidObjectException
/**
*
* ScaledPicture responsible for compressing the bitmap efficiently
*/
class ScaledPicture(private var uri: Uri?, private var resolver: ContentResolver) {
private var path: String? = null
private var orientation: Matrix? = null
private var storedHeight: Int = 0
private var storedWidth: Int = 0
@Throws(IOException::class)
private fun getInformation(): Boolean {
/*if (getInformationFromMediaDatabase())
return true;*/
return getInformationFromFileSystem()
}
/* Support for file managers and dropbox */
@Throws(IOException::class)
private fun getInformationFromFileSystem(): Boolean {
path = uri?.path
if (path == null)
return false
val exif = ExifInterface(path.toString())
val orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL)
this.orientation = Matrix()
when (orientation) {
ExifInterface.ORIENTATION_NORMAL -> {
}
ExifInterface.ORIENTATION_FLIP_HORIZONTAL -> this.orientation?.setScale(-1f, 1f)
ExifInterface.ORIENTATION_ROTATE_180 -> this.orientation?.setRotate(180f)
ExifInterface.ORIENTATION_FLIP_VERTICAL -> this.orientation?.setScale(1f, -1f)
ExifInterface.ORIENTATION_TRANSPOSE -> {
this.orientation?.setRotate(90f)
this.orientation?.postScale(-1f, 1f)
}
ExifInterface.ORIENTATION_ROTATE_90 -> this.orientation?.setRotate(90f)
ExifInterface.ORIENTATION_TRANSVERSE -> {
this.orientation?.setRotate(-90f)
this.orientation?.postScale(-1f, 1f)
}
ExifInterface.ORIENTATION_ROTATE_270 -> this.orientation?.setRotate(-90f)
}/* Identity matrix */
return true
}
@Throws(IOException::class)
private fun getStoredDimensions(): Boolean {
val input = resolver.openInputStream(uri)
val options = BitmapFactory.Options()
options.inJustDecodeBounds = true
BitmapFactory.decodeStream(resolver.openInputStream(uri), null, options)
/* The input stream could be reset instead of closed and reopened if it were possible
to reliably wrap the input stream on a buffered stream, but it's not possible because
decodeStream() places an upper read limit of 1024 bytes for a reset to be made (it calls
mark(1024) on the stream). */
input?.close()
if (options.outHeight <= 0 || options.outWidth <= 0)
return false
storedHeight = options.outHeight
storedWidth = options.outWidth
return true
}
@Throws(IOException::class)
fun getBitmap(reqWidth: Int, reqHeight: Int): Bitmap {
val heightWidth = 1000
if (!getInformation())
throw FileNotFoundException()
if (!getStoredDimensions())
throw InvalidObjectException(null)
val rect = RectF(0f, 0f, storedWidth.toFloat(), storedHeight.toFloat())
orientation?.mapRect(rect)
var width = rect.width().toInt()
var height = rect.height().toInt()
var subSample = 1
while (width > heightWidth || height > heightWidth) {
width /= 2
height /= 2
subSample *= 2
}
if (width == 0 || height == 0)
throw InvalidObjectException(null)
val options = BitmapFactory.Options()
options.inSampleSize = subSample
val subSampled = BitmapFactory.decodeStream(resolver.openInputStream(uri), null, options)
val picture: Bitmap
if (orientation?.isIdentity == false) {
picture = Bitmap.createBitmap(subSampled, 0, 0, options.outWidth, options.outHeight,
orientation, false)
subSampled.recycle()
} else
picture = subSampled
return ImageScalingUtils.decodeBitmap(picture, reqWidth, reqHeight, ImageScalingUtils.ScalingLogic.CROP)
}
}
将上述类复制到您的项目中,并像这样使用它
var bitmap = ScaledPicture(mSelectedUri, contentResolver).getBitmap(800, 800)
传递所需的高度和宽度