I have getting one problem, when i am convert view to bitmap then resize bitmap it's getting low quality of image using scale.
My code is here,
`fun scaleBitmap(bitmap: Bitmap, wantedWidth: Int, wantedHeight: Int): Bitmap? {
val originalWidth = bitmap.width.toFloat()
val originalHeight = bitmap.height.toFloat()
val output =Bitmap.createBitmap(wantedWidth,wantedHeight,Bitmap.Config.ARGB_8888)
val canvas = Canvas(output)
val m = Matrix()
val scalex = wantedWidth / originalWidth
val scaley = wantedHeight / originalHeight
val xTranslation = 0.2f
val yTranslation = (wantedHeight - originalHeight * scaley) / 1.0f
m.postScale(scalex, scaley)
m.postTranslate(xTranslation, yTranslation)
canvas.drawBitmap(bitmap, m, Paint(Paint.FILTER_BITMAP_FLAG))
return output
}`
Related
fun resize(x: Bitmap, max: Int): Bitmap {
var width = x.width
var height = x.height
val scale: Double = width.toDouble() / height.toDouble()
if (scale > 1) {
width = max
var newHeight = width / scale
height = newHeight.toInt()
} else {
height = max
var newWidth = height * scale
width = newWidth.toInt()
}
return Bitmap.createScaledBitmap(x, width / 2, height / 2, true)
}
This is the code to execute it
val smallBitmap = small(bitmap!!, 300)
val outputStream = ByteArrayOutputStream()
smallBitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
val byteArray = outputStream.toByteArray()
I have 2 fragments. And I am picking photo from the gallery and pass it to other fragment. And when I send it the photos come out too pixelated and blurry. It's because of resize and scaling. But I do not know what to do.
I am trying to make an extension function to use it in a different class. I am trying to create it but it does not work. Can anyone solve this problem.
Here is my extension:
fun resize.toBitmap(image: Bitmap, maxWidth: Int, maxHeight: Int): Bitmap {
var image = image
return if (maxHeight > 0 && maxWidth > 0) {
val width = image.width
val height = image.height
val ratioBitmap = width.toFloat() / height.toFloat()
val ratioMax = maxWidth.toFloat() / maxHeight.toFloat()
var finalWidth = maxWidth
var finalHeight = maxHeight
if (ratioMax > ratioBitmap) {
finalWidth = (maxHeight.toFloat() * ratioBitmap).toInt()
} else {
finalHeight = (maxWidth.toFloat() / ratioBitmap).toInt()
}
image = Bitmap.createScaledBitmap(image, finalWidth, finalHeight, true)
image
} else {
image
}
And this is how I try to reach it:
var bitmap = Bitmap.createBitmap(drawingCacheBitmap)
bitmap = resize(bitmap, 200, 100)
Try this
fun Bitmap.resizeImage(image: Bitmap, maxWidth: Int, maxHeight: Int): Bitmap {
val width = image.width
val height = image.height
val scaleWidth = maxWidth.toFloat() / width
val scaleHeight = maxHeight.toFloat() / height
val matrix = Matrix()
matrix.postScale(scaleWidth, scaleHeight)
// Create a New bitmap
val resizedBitmap = Bitmap.createBitmap(
image, 0, 0, width, height, matrix, false)
resizedBitmap.recycle()
return resizedBitmap
}
And call this extension function like this,
bitmap = resizeImage(bitmap, 200, 100)
How i can set bitmap image in center it is not in center .Here is my code and screen.I tried so much but I failed to solves this
fun onDraw(c: Canvas, rectF: RectF, pos: Int) {
val p = Paint()
p.color = color
c.drawRect(rectF, p)
p.color = Color.WHITE
p.textSize - textSize.toFloat()
var r = Rect()
val cHeight = rectF.height()
val cWidth = rectF.width()
p.textAlign = Paint.Align.RIGHT
p.getTextBounds(text, 0, text.length, r)
var x = 0f
var y = 0f
if (imageResId == 0) {
x = cWidth / 2f - r.width() / 2f - r.left.toFloat()
y = cHeight / 2f + r.height() / 2f - r.bottom.toFloat()
c.drawText(text, rectF.left + x, rectF.top + y, p)
} else {
val d = ContextCompat.getDrawable(context, imageResId)
val bitmap = drawableToBitmap(d!!)
c.drawBitmap(
bitmap,
(rectF.left + rectF.right) / 2,
(rectF.top + rectF.bottom) / 2,
p
)
}
clickRegion = rectF
this.pos = pos
}
Here is image link that is produce error
enter link description here
private fun drawableToBitmap(d: Drawable?): Bitmap {
if (d is BitmapDrawable) return d.bitmap
val bitmap =
Bitmap.createBitmap(d!!.intrinsicWidth, d.intrinsicHeight, Bitmap.Config.ARGB_8888)
var canvas = Canvas(bitmap)
d.setBounds(0, 0, canvas.width, canvas.height)
d.draw(canvas)
return bitmap
}
You can see that your drawables are all in center and draw from there, all you do are right, you just only need a simply offset with:
Subtract the half of the drawable's width & height from the start position
Red to Green
Code Snippet
c.drawBitmap(
bitmap,
(rectF.left + rectF.right) / 2,
(rectF.top + rectF.bottom) / 2,
p
)
To
c.drawBitmap(
bitmap,
(rectF.left + rectF.right - bitmap.width) / 2,
(rectF.top + rectF.bottom - bitmap.height) / 2,
p
)
I am trying to draw a border on an image with a squircle mask using a Picasso Transformation. The squircle mask is a VectorDrawable.
I think the easiest and most flexible way to do this is to first draw a larger squircle of a desired border color using canvas.drawPaint. Then draw a smaller squircle using the photo bitmap using canvas.drawBitmap. I can draw them both separately, I can scale the bitmap and draw it with the mask successfully, but any time I try to combine the two it loses the mask on the canvas.drawBitmap call. Any ideas on what I could be doing wrong?
I have tried loads of blend mode options but I don't think that is the issue.
override fun transform(source: Bitmap): Bitmap {
val width = source.width
val height = source.height
val borderWidth = 100
val output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(output)
//Draw a full size, red squircle
val paint = Paint()
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
paint.color = Color.RED
val mask = context.getDrawable(maskID)
mask.setBounds(0, 0, width, height)
mask.draw(canvas)
canvas.drawPaint(paint)
//Draw a masked, scaled down bitmap of the photo on top
val bitmapPaint = Paint()
bitmapPaint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
val bitmapMask = context.getDrawable(maskID)
bitmapMask.setBounds(borderWidth / 2, borderWidth / 2, width - borderWidth / 2, height - borderWidth / 2)
bitmapMask.draw(canvas)
val sourceDrawable = source.toDrawable(context.resources)
sourceDrawable.setBounds(borderWidth / 2, borderWidth / 2, width - borderWidth / 2, height - borderWidth / 2)
canvas.drawBitmap(sourceDrawable.bitmap, null,
Rect(borderWidth / 2, borderWidth / 2, width - borderWidth / 2, height - borderWidth / 2),
bitmapPaint)
source.recycle()
return output
}
Result:
If I comment out the call to drawBitmap I get this result (which is nearly there!):
UPDATED 27/11/2018
I've solved the problem by drawing the picture on a temp canvas with desired mask, then drawing the result bitmap over the main canvas. The source code and visual result are included here:
MaskTransformation.kt
import android.content.Context
import android.graphics.*
import android.graphics.drawable.BitmapDrawable
import android.support.annotation.DrawableRes
import android.support.v4.content.ContextCompat
import com.squareup.picasso.Transformation
class MaskTransformation(
private val context: Context,
#DrawableRes private val maskID: Int
) : Transformation {
override fun key(): String {
return "mask"
}
override fun transform(source: Bitmap): Bitmap {
val width = source.width
val height = source.height
val borderWidth = 400
val output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(output)
//Draw a full size, red squircle
val paint = Paint()
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
paint.color = Color.RED
val mask = ContextCompat.getDrawable(context, maskID)!!
mask.setBounds(0, 0, width, height)
mask.draw(canvas)
canvas.drawPaint(paint)
//Draw a masked, scaled down bitmap of the photo on top
val maskingPaint = Paint()
maskingPaint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
val maskDrawable = ContextCompat.getDrawable(context, maskID)!!
maskDrawable.setBounds(borderWidth / 2, borderWidth / 2, width - borderWidth / 2, height - borderWidth / 2)
val overlayBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val overlayCanvas = Canvas(overlayBitmap)
maskDrawable.draw(overlayCanvas)
val pictureBitmap = Bitmap.createBitmap(width - borderWidth, height - borderWidth, Bitmap.Config.ARGB_8888)
val pictureCanvas = Canvas(pictureBitmap)
val sourceDrawable = BitmapDrawable(context.resources, source)
sourceDrawable.setBounds(borderWidth / 2, borderWidth / 2, width - borderWidth / 2, height - borderWidth / 2)
pictureCanvas.drawBitmap(
sourceDrawable.bitmap,
null,
Rect(0, 0, width - borderWidth, height - borderWidth),
Paint()
)
overlayCanvas.drawBitmap(pictureBitmap, (borderWidth / 2).toFloat(), (borderWidth / 2).toFloat(), maskingPaint)
canvas.drawBitmap(overlayBitmap, 0f, 0f, Paint())
source.recycle()
return output
}
}
MainActivity.kt
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import com.squareup.picasso.Picasso
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Picasso.get()
.load(R.drawable.img_aminography)
.transform(MaskTransformation(this, R.drawable.ic_squircle))
.into(imageView)
}
}
ic_squircle.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="32"
android:viewportHeight="32">
<path android:fillColor="#000000"
android:pathData="M31.2,14.3v3.5c0,9.8,-5.9,13.5,-13.4,13.5h-3.5c-7.7,0,-13.5,-3.4,-13.5,-13.5v-3.5c0,-10.8,6,-13.5,13.5,-13.5h3.5C25.2,0.8,31.2,4.1,31.2,14.3"/>
</vector>
.
Visual Result
I am using the zing library for generating the QR code and I have generated the simple QR Code using URL,Text etc. but my question is that how can i generate the QR Code with company logo in middle of Qr Code.
I have found so many answer in stack overflow but non of them can solve my problem.
I already generated for my project (Kotlin answer)
fun CreateQRCode(qrCodeData: String) {
try {
val hintMap = HashMap<EncodeHintType, ErrorCorrectionLevel>()
val width = 250
val height = 250
val smallestDimension = if (width < height) width else height
hintMap[EncodeHintType.ERROR_CORRECTION] = ErrorCorrectionLevel.H
val qrCodeWriter = QRCodeWriter()
val bitMatrix = qrCodeWriter.encode(
qrCodeData,
BarcodeFormat.QR_CODE,
smallestDimension, smallestDimension) // width x height
val pixels = IntArray(smallestDimension * smallestDimension)
// All are 0, or black, by default
for (y in 0 until height) {
val offset = y * smallestDimension
for (x in 0 until smallestDimension) {
//pixels[offset + x] = matrix.get(x, y) ? BLACK : WHITE;
pixels[offset + x] = if (bitMatrix.get(x, y))
ResourcesCompat.getColor(resources, R.color.colorPrimary, null)
else
Color.WHITE
}
}
// var image = DataMatrixWriter.toBufferedImage(bitMatrix)
// Load logo image
// var overly = getOverly(LOGO);
val bitmap = Bitmap.createBitmap(smallestDimension, smallestDimension, Bitmap.Config.ARGB_8888)
bitmap.setPixels(pixels, 0, smallestDimension, 0, 0, smallestDimension, smallestDimension)
//setting bitmap to image view
val options = BitmapFactory.Options()
options.outWidth = 250
options.inJustDecodeBounds = false
options.outHeight = 250
var overlay = BitmapFactory.decodeResource(getResources(), R.mipmap.sugary_qr_icon, options);
overlay = Bitmap.createScaledBitmap(overlay, 50, 50, true)
val merged = mergeBitmaps(overlay, bitmap)
var _params = RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT)
_params.addRule(Gravity.CENTER_VERTICAL)
// ivQrCode!!.setPadding(180, 180, 180, 180)
ivQrCode!!.layoutParams = _params;
ivQrCode!!.setImageBitmap(merged)
// return bitmap;
} catch (er: Exception) {
if (debug)
er.printStackTrace()
}
}
mergeBitmaps function
private fun mergeBitmaps(overlay: Bitmap, bitmap: Bitmap): Bitmap {
val height = bitmap.height
val width = bitmap.width
val combined = Bitmap.createBitmap(width, height, bitmap.config)
val canvas = Canvas(combined)
val canvasWidth = canvas.width
val canvasHeight = canvas.height
canvas.drawBitmap(bitmap, Matrix(), null)
Log.e("WIDTH", canvasWidth.toString() + " " + overlay.width)
val centreX = (canvasWidth - overlay.width) / 2
val centreY = (canvasHeight - overlay.height) / 2
canvas.drawBitmap(overlay, centreX.toFloat(), centreY.toFloat(), null)
val bmOverlay = Bitmap.createBitmap(overlay.width, overlay.height, overlay.config);
var canvas = Canvas(bmOverlay);
canvas.drawBitmap(overlay, Matrix(), null);
canvas.drawBitmap(bitmap, 0f, 0f, null);
return bmOverlay
}