Usman Ali
Usman Ali

Reputation: 433

add Logo on images Android

I am working on Android app that has to put frame and Logo on Image at a Time, The Problem I am facing is Frame is Coming from first Fragment and the Logo from Second Fragment. I am Setting the Frame on Bitmap image on imageView as well as Logo.

The Issue I am facing is, as I successfully Successfully Add Frame on Bitmap image, and I try to also set Logo on Bitmap image it Remove the Frame and Set the Logo on Bitmap and vice versa..

What I really want is Frame and Logo are set on Bitmap at a time...

Here, where Logo Coming From First Fragment Adapter to main Activity via Method..

 holder.iconslogo.setOnClickListener {
        when (charItemlogo.itemsidlogo) {
            1 -> {
               var btmp=  arrayList[0].iconslogo
                (context as MakeStylishActivity).setLogos(btmp)
            }

Here the Frame is Coming from Frame Fragment to Main Activity

  holder.iconsframe.setOnClickListener {

        when (charItemFrame.itemsidframe) {
            1 -> {
               var btmp=  arrayList[0].iconsframe
                (context as MakeStylishActivity).setFrames(btmp)
            }}

This is Main Activity that is Setting the Logo and Frame to Bitmap

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_make_stylish)
    val byteArray = intent.getByteArrayExtra("pictures")
    bmp = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size)!!
    img_bitmap1.setImageBitmap(bmp)
    stringqrcontent= intent.getStringExtra("qrcontent")

    bottom_nav_viewstyle.setOnNavigationItemSelectedListener {
        when (it.itemId) {
            R.id.action_default -> {
                true
            }
            R.id.action_colors -> {
                ShowFColorFragment()
                true
            }
            R.id.action_logos -> {
                ShowLogoFragment()
                true
            }
            R.id.action_frames -> {
                FunctionAddFrames();
                true
            }
            R.id.action_patterns -> {
                true
            }
            else -> false
        }
    }
}

fun setLogos(btmp: Bitmap?) {
    //img_bitmap1.setImageBitmap(btmp)
    PutLogoOnQRBitmaps(btmp, bmp!!)
}

fun setFrames(btmp: Bitmap?) {
   // img_bitmap1.setImageBitmap(btmp)
    //addWhiteBorder(bmp!!,10)
    PutFrameImages(btmp, bmp!!)
}

//Combine Frame Behind QR Code
fun PutFrameImages(frame: Bitmap?, image: Bitmap): Bitmap? {
    var cs: Bitmap? = null
    var rs: Bitmap? = null
    rs = Bitmap.createScaledBitmap(frame!!, image.width, image.height, true)
    cs = Bitmap.createBitmap(rs.width, rs.height, Bitmap.Config.RGB_565)
    val comboImage = Canvas(cs)
    comboImage.drawBitmap(image, 0F, 0F, null)
    comboImage.drawBitmap(rs, 0F, 0F, null)
    if (rs != null) {
        rs.recycle()
        rs = null
    }
   // Runtime.getRuntime().gc()
    img_bitmap1.setImageBitmap(cs!!)
    return cs
}


//Put Logo on QR Code
fun PutLogoOnQRBitmaps(logo: Bitmap?, qrcode: Bitmap): Bitmap? {
    val combined = Bitmap.createBitmap(qrcode.width, qrcode.height, qrcode.config)
    val canvas = Canvas(combined)
    val canvasWidth = canvas.width
    val canvasHeight = canvas.height
    canvas.drawBitmap(qrcode, Matrix(), null)
    val resizeLogo = Bitmap.createScaledBitmap(logo!!, canvasWidth / 5, canvasHeight / 5, true)
    val centreX = (canvasWidth - resizeLogo.width) / 2
    val centreY = (canvasHeight - resizeLogo.height) / 2
    canvas.drawBitmap(resizeLogo, centreX.toFloat(), centreY.toFloat(), null)

    img_bitmap1.setImageBitmap(combined)
    return combined
}}

Upvotes: 0

Views: 190

Answers (1)

Martin Marconcini
Martin Marconcini

Reputation: 27226

I see a few things here that aren't considered a good idea, but the most important is that the size of an Intent has a limit (very small, that is) and is not designed to pass large amounts of data.

What I would do

Regardless of your simplistic Architecture (no usage of ViewModels, or correct separation of concerns, and a few other SOLID principles ignored here...), I would not pass the image via intent. Instead, I would save the image to the filesystem (temporarily), pass the "path" as a string to the next activity, and have said activity open the file and create the Bitmap from the filesystem.

This means you no longer need to worry about going overboard with the image size/intent size, and that your two activities decouple a little bit. You can now pass any path to a bitmap there and the other activity will pick it up, regardless of where it came from.

A second improvement would be to delegate all this (image storing, passing, retrieving, etc.) to a ViewModel + UseCase (and/or Repository), in which case you'd be further decoupling your code. For this, and much more, the starting point would be getting started with Android Jetpack; I recommend at least trying to leverage a ViewModel in your architecture.

You'd also want to be careful when creating bitmaps out of nowhere, you can easily run out of memory by doing what you're doing; you should take a look at Android's official documentation about handling large bitmaps.

Upvotes: 1

Related Questions