কম্পিউটার টিউটোরিয়াল

অ্যান্ড্রয়েডে Bitmap-এ থেকে ফ্রি-হ্যান্ড গোলাকার এলাকা কাটা (Crop)

Touch Event এবং Path ব্যবহার করে ম্যানুয়ালি গোলাকার এলাকা কাটা

এই উদাহরণে দেখানো হয়েছে কিভাবে ব্যবহারকারী আঙুল দিয়ে স্ক্রিনে পথ আঁকলে (free-hand drawing) সেই পথ অনুযায়ী Bitmap-এ থেকে সেই এলাকা কাটা (crop) যায়। Path, Canvas, PorterDuffXfermode ব্যবহার করা হয়েছে।

ধাপ ১: প্রজেক্ট তৈরি করুন

Android Studio-তে নতুন প্রজেক্ট শুরু করুন।

ধাপ ২: লেআউট (activity_main.xml) - খালি RelativeLayout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" />

ধাপ ৩: MainActivity.java - কাস্টম View (CutImage)

package com.example.sample;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // কাস্টম View সেট করুন
        setContentView(new CutImage(this));
    }

    // কাস্টম View ক্লাস
    static class CutImage extends View {
        Bitmap bitmap;
        Path path = new Path();
        Paint paint = new Paint();
        Paint cropPaint = new Paint();

        public CutImage(Context context) {
            super(context);
            // ড্রয়েবল থেকে Bitmap লোড করুন
            bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.demo);
            
            // ড্রইং পেইন্ট (লাল রঙের স্ট্রোক)
            paint.setColor(Color.RED);
            paint.setStyle(Paint.Style.STROKE);
            paint.setStrokeWidth(5f);
            
            // ক্রপিং পেইন্ট
            cropPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        }

        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            // মূল bitmap আঁকুন
            canvas.drawBitmap(bitmap, 0, 0, null);
            // ব্যবহারকারীর আঁকা পথ আঁকুন
            canvas.drawPath(path, paint);
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            float x = event.getX();
            float y = event.getY();

            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    path.moveTo(x, y);
                    break;
                case MotionEvent.ACTION_MOVE:
                case MotionEvent.ACTION_UP:
                    path.lineTo(x, y);
                    cropBitmap(); // পথ পুরো হলে ক্রপ করুন
                    break;
            }
            invalidate(); // রি-ড্র চাইये
            return true;
        }

        private void cropBitmap() {
            // নতুন Bitmap তৈরি করুন (ক্রপড)
            Bitmap cropped = Bitmap.createBitmap(
                bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
            Canvas cropCanvas = new Canvas(cropped);
            
            // পথ অনুযায়ী আঁকুন (মাস্ক হিসেবে)
            cropCanvas.drawPath(path, cropPaint);
            // মূল bitmap পথের ওপর আঁকুন (SRC_IN মোডে)
            cropCanvas.drawBitmap(bitmap, 0, 0, cropPaint);
            
            // পুরানো bitmap রিসাইকেল করুন, নতুনটি সেট করুন
            bitmap.recycle();
            bitmap = cropped;
            path.reset(); // পথ রিসেট করুন পরবর্তী ড্রইং-এর জন্য
        }
    }
}

কিভাবে কাজ করে

  1. ব্যবহারকারী স্ক্রিনে আঙুল টেনে পথ আঁকে (ACTION_MOVE)।
  2. আঙুল ছাড়লে (ACTION_UP) cropBitmap() কল হয়।
  3. একটি নতুন Canvas-এ পথ আঁকা হয় (মাস্ক) এবং SRC_IN মোডে মূল bitmap আঁকা হয়।
  4. ফলাফল: শুধু পথের ভেতরের অংশই থাকে, বাকি ট্রান্সপেরেন্ট হয়।

সীমাবদ্ধতা

  • পথ বন্ধ (closed) না হলে ফলাফল অপ্রত্যাশিত হতে পারে — path.close() কল করা উচিত।
  • বড় Bitmap-এ মেমরি সমস্যা হতে পারে।
  • প্রোডাকশনে BitmapShader বা লাইব্রেরি (যেমন uCrop, CropImage) ব্যবহার করা ভালো।

ফলাফল

অ্যাপ চালু করলে ছবি দেখাবে। আঙুল দিয়ে আঁকলে লাল লাইন দেখাবে, আঙুল তুললে সেটি গোলাকার/ফ্রি-ফর্মে কাটা হয়ে যাবে।

অ্যান্ড্রয়েডে Bitmap-এ থেকে ফ্রি-হ্যান্ড গোলাকার এলাকা কাটা (Crop) অ্যান্ড্রয়েডে Bitmap-এ থেকে ফ্রি-হ্যান্ড গোলাকার এলাকা কাটা (Crop)
ফ্রি-হ্যান্ড পথ আঁকা → ক্রপড Bitmap
  1. অ্যান্ড্রয়েডে Drawable কে Bitmap-এ রূপান্তর করা

  2. অ্যান্ড্রয়েড থেকে ম্যালওয়্যার সরানোর উপায়

  3. Android থেকে AirTags খুঁজে বের করার পদ্ধতি?

  4. অ্যান্ড্রয়েড থেকে পিসিতে ফাইল ট্রান্সফার: দ্রুত ও নিরাপদে ধাপে ধাপে গাইড