Kotlin - thermal printer Arabic text never printed - android

Am using DantSu library to print receipts but Arabic text is never printed
here is my code
val printer = EscPosPrinter(
deviceConnection,
printerData.printerDpi,
printerData.printerWidthMM,
printerData.printerNbrCharactersPerLine,
EscPosCharsetEncoding("windows-1252", 16)
)

According to this comment on the issue on the library .. we found a solution but not totally correct
private fun getBitmap(text: String): Bitmap? {
val paint = Paint()
paint.setTextSize(28f)
val bounds = Rect()
paint.getTextBounds(text, 0, text.length, bounds)
val width: Int = bounds.width()
val height: Int = bounds.height()
val bitmap = Bitmap.createBitmap(width * 2, height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
canvas.drawColor(Color.WHITE)
canvas.drawText(text, 20f, 20f, paint)
return bitmap
}

Related

How can I make a circle image in an app widget?

I can't seem to figure out how can I make an image (such as ImageView) a circle image, inside an app widget. I mean crop it in the form of a circle, like .clipShape(Circle()) in SwiftUI.
I tried some solutions but they won't work in widgets:
ShapeableImageView breaks the widget
Androidx library is not allowed in widget
Any other solutions?
Updated
I have tried doing it programatically from Kotlin, converting the solution from here:
class AppWidgetProvider : HomeWidgetProvider() {
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray, widgetData: SharedPreferences) {
appWidgetIds.forEach { widgetId ->
val view = RemoteViews(context.packageName, R.layout.widget_layout)
val pendingIntent = HomeWidgetLaunchIntent.getActivity(
context,
MainActivity::class.java,
Uri.parse("https://example.com"))
view.setOnClickPendingIntent(R.id.widgetRoot, pendingIntent)
val logoBitmap = BitmapFactory.decodeResource(context.resources, R.drawable.app_icon)
view.setImageViewBitmap(R.id.smarthutsLogo, getCroppedBitmap(logoBitmap))
appWidgetManager.updateAppWidget(widgetId, view)
}
}
#Throws(Exception::class)
fun getCroppedBitmap(bitmap: Bitmap): Bitmap {
val output: Bitmap =
Bitmap.createBitmap(bitmap.width, bitmap.height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(output)
val color = -0xbdbdbe
val paint = Paint()
val rect = Rect(0, 0, bitmap.width, bitmap.height)
paint.isAntiAlias = true
canvas.drawARGB(0, 0, 0, 0)
paint.color = color
canvas.drawCircle(
(bitmap.width / 2).toFloat(),
(bitmap.height / 2).toFloat(),
(bitmap.width / 2).toFloat(),
paint
)
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
canvas.drawBitmap(bitmap, rect, rect, paint)
return output
}
}
HomeWidgetProvider is from a Flutter plugin, you can find the code for it here.
What happens is that the the image despite being being cropped as a circle it's shown with a white square background.
From this issue, using Android Studio's code converter, I managed to make a solution in Kotlin:
#Throws(Exception::class)
fun getCroppedBitmap(bitmap: Bitmap): Bitmap {
val output: Bitmap =
Bitmap.createBitmap(bitmap.width, bitmap.height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(output)
val paint = Paint()
val rect = Rect(0, 0, bitmap.width, bitmap.height)
paint.isAntiAlias = true
canvas.drawCircle(
(bitmap.width / 2).toFloat(),
(bitmap.height / 2).toFloat(),
(bitmap.width / 2).toFloat(),
paint
)
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
canvas.drawBitmap(bitmap, rect, rect, paint)
return output
}
The newly created function can be used inside the widget's onUpdate method as follows:
val view = RemoteViews(context.packageName, R.layout.widget_layout)
val logoBitmap = BitmapFactory.decodeResource(context.resources, R.drawable.app_icon)
view.setImageViewBitmap(R.id.imageView, getCroppedBitmap(logoBitmap))
Be careful not have android:background="#android:color/white" added to your ImageView. If you need to add a background color, add it when creating the bitmap.

Create border for custom drawable mask when image transform with Android

I have this masked transformation class, that can receive any mask:
class MaskedTransformation(private val maskDrawable: Drawable) : Transformation {
override fun key(): String = maskDrawable.hashCode().toString()
override fun transform(source: Bitmap): Bitmap? {
val result = Bitmap.createBitmap(source.width, source.height, Bitmap.Config.ARGB_8888)
val mCanvas = Canvas(result)
val o = BitmapFactory.Options()
o.inSampleSize = 2
val mask = Bitmap.createBitmap(source.width, source.height, Bitmap.Config.ARGB_8888)
val tmpCanvas = Canvas(mask)
val maskRaw9Patch = maskDrawable as? NinePatchDrawable
maskRaw9Patch?.setBounds(0, 0, tmpCanvas.width, tmpCanvas.height)
maskRaw9Patch?.draw(tmpCanvas)
val paint = Paint(Paint.ANTI_ALIAS_FLAG)
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_IN)
mCanvas.drawBitmap(source, 0f, 0f, null)
mCanvas.drawBitmap(mask, 0f, 0f, paint)
paint.xfermode = null
source.recycle()
return result
}
For example, we can have this form: or any other.
How to add border (shape) around it? Please help!

Path is filled with color instead showing as contour

I faced the following problem: I need to show the contour of the human face over bitmap. I have coordinates of the face contour points. Here's my code:
private fun detectContours(
it: FirebaseVisionFace,
icon: Bitmap
) {
val faceContour = it.getContour(FirebaseVisionFaceContour.FACE)
val mutableBitmap = icon.copy(
Bitmap.Config.ARGB_8888, true
)
val canvas = Canvas(mutableBitmap)
val paint = Paint(Paint.ANTI_ALIAS_FLAG)
paint.color = Color.parseColor("#99ff0000")
val path = Path()
path.moveTo(faceContour.points[0].x, faceContour.points[0].y)
faceContour.points.forEach {
path.lineTo(it.x, it.y)
}
path.close()
canvas.drawPath(path, paint)
binding.ivPhoto.setImageBitmap(mutableBitmap)
}
Here I use path.moveTo(...) and I expect that mutableBitmap will look like a face with the contour. But when I run the app I see the following result:
So, why the path is filled with the colour. Thanks in advance, I will appreciate any help
Fixed by changing path.drawline to canvas.drawLine
val faceContour = it.getContour(FirebaseVisionFaceContour.FACE)
var startX = faceContour.points[0].x
var startY = faceContour.points[0].y
val initialX = faceContour.points[0].x
val initialY = faceContour.points[0].y
val paint = Paint(Paint.ANTI_ALIAS_FLAG)
paint.color = Color.parseColor("#ff0000")
faceContour.points.forEach {
canvas.drawLine(startX, startY, it.x, it.y, paint)
startX = it.x
startY = it.y
}
canvas.drawLine(startX, startY, initialX, initialY, paint)

Draw transparent bitmap on backgound

I want to draw transparent bitmaps on a background in a game. However, the bitmap is not transparent, it still has white color in the background. Here is my code
inner class Canvass(context: Context) : View(context) {
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
val frame_paint: Paint = Paint()
frame_paint.style = Paint.Style.FILL
frame_paint.isAntiAlias = true
val framegame = BitmapFactory.decodeResource (resources, R.drawable.frame)
canvas.drawBitmap (framegame, 0f, 0f, frame_paint)
canvas.drawPath(mPath, mPaint)
val tennis_paint: Paint = Paint()
tennis_paint.style = Paint.Style.FILL
tennis_paint.color = Color.TRANSPARENT
tennis_paint.isAntiAlias = true
val tennis = BitmapFactory.decodeResource (resources, R.drawable.tennis_ball)
canvas.drawBitmap (tennis, 50f, 200f, tennis_paint)
}
}
I found this code, it works for me.
val tennis_paint: Paint = Paint()
tennis_paint.style = Paint.Style.FILL
tennis_paint.isAntiAlias = true
val tennis = BitmapFactory.decodeResource (resources, R.drawable.tennis_ball)
var bitmap = transparent_bitmap(tennis)
canvas.drawBitmap (bitmap, 50f, 300f, tennis_paint)
fun transparent_bitmap(bmp:Bitmap):Bitmap{
var bitmap: Bitmap = Bitmap.createBitmap(
bmp.width,
bmp.height,
Bitmap.Config.ARGB_8888
)
bitmap.setHasAlpha(true)
for (x in 1..bmp.width-1){
for (y in 1..bmp.height-1){
var pixel = bmp.getPixel(x,y)
val redValue = Color.red(pixel)
val blueValue = Color.blue(pixel)
val greenValue = Color.green(pixel)
if ((redValue==255)and(blueValue==255)and(greenValue==255)){
bitmap.setPixel(x,y,Color.argb(1,0,0,0))
}else {
bitmap.setPixel(x,y,Color.rgb(redValue,greenValue,blueValue))
}
}
}
return bitmap
}

canvas.drawBitmap - Software rendering doesn't support hardware bitmaps

simple fun
fun getCircleBitmap(bitmap: Bitmap, recycle: Boolean): Bitmap {
val paint = Paint()
paint.isAntiAlias = true
paint.color = Color.WHITE
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
val rect = Rect(0, 0, bitmap.width, bitmap.height)
val rectF = RectF(rect)
val output = Bitmap.createBitmap(bitmap.width, bitmap.height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(output)
canvas.drawARGB(0, 0, 0, 0)
canvas.drawOval(rectF, paint)
canvas.drawBitmap(bitmap, rect, rect, paint)
if (recycle) {
bitmap.recycle()
}
return output
}
Taget API 29. Emulator API 28. Kotlin 1.3.40.
About month ago this fun worked. But now on "canvas.drawBitmap" error "Software rendering doesn't support hardware bitmaps". Try android:hardwareAccelerated="false" - same error. Why?
so, my solution:
fun getCircleBitmapDrawable(bitmap: Bitmap): RoundedBitmapDrawable {
val round = RoundedBitmapDrawableFactory.create(context.resources, bitmap)
round.isCircular = true
round.setAntiAlias(true)
return round
}

Categories

Resources