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

Android-এ Picasso লাইব্রেরি ব্যবহার করে ইমেজ ডাউনলোড এবং প্রদর্শন

Android-এ Picasso লাইব্রেরি ব্যবহার করে ইমেজ ডাউনলোড এবং প্রদর্শন

Picasso Square Inc. দ্বারা विकসিত একটি জনপ্রিয় ইমেজ লোডিং লাইব্রেরি যা ইমেজ ডাউনলোড, ক্যাশিং, রিসাইজিং এবং প্রদর্শন খুব সহজ করে দেয়। এটি অ্যাসিঙ্ক্রোনাসলি কাজ করে এবং মেমরি ম্যানেজমেন্ট স্বয়ংক্রিয়ভাবে হ্যান্ডেল করে।

📌 দ্রষ্টব্য: Picasso-এর नवীনतम ভার্সন (2.71828+) AndroidX সাপোর্ট করে। পুরানো ভার্সন (2.5.x) ব্যবহার করলে মাইগ্রেশন প্রয়োজন হতে পারে। নতুন প্রজেক্টের জন্য Coil বা Glide ব্যবহার করার পরামর্শ দেওয়া হয়।

প্রয়োজনীয় ধাপসমূহ

ধাপ ১: নতুন প্রজেক্ট তৈরি করুন এবং ডিপেন্ডেন্সি যোগ করুন

Android Studio-তে File → New Project এ যান। তারপর build.gradle (Module: app) ফাইলে:

dependencies {
    // Picasso नवীনतम ভার্সন
    implementation 'com.squareup.picasso:picasso:2.71828'

    // অথবা পুরানো ভার্সন (যদি লিগ্যাসি সাপোর্ট দরকার হয়)
    // implementation 'com.squareup.picasso:picasso:2.5.2'
}

ধাপ ২: লেআউট ফাইল (res/layout/activity_main.xml)

<?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"
    android:padding="4dp"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/btnDownload"
        android:scaleType="centerCrop"
        android:contentDescription="ডাউনলোড করা ছবি" />

    <Button
        android:id="@+id/btnDownload"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:textAlignment="center"
        android:text="ইমেজ ডাউনলোড করুন" />

</RelativeLayout>

ধাপ ৩: MainActivity.java বাস্তবায়ন করুন

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import com.squareup.picasso.Callback;
import com.squareup.picasso.Picasso;

public class MainActivity extends AppCompatActivity {

    ImageView imageView;
    Button btnDownload;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        imageView = findViewById(R.id.imageView);
        btnDownload = findViewById(R.id.btnDownload);

        btnDownload.setOnClickListener(v -> {
            String imageUrl = "https://images.pexels.com/photos/1212487/pexels-photo-1212487.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260";

            // Picasso-এ মৌলিক লোডিং
            Picasso.get()
                    .load(imageUrl)
                    .placeholder(R.drawable.placeholder) // লোডিং সময় প্লেসহোল্ডার (ঐচ্ছিক)
                    .error(R.drawable.error_image)       // ত্রুটি হলে এরর ইমেজ (ঐচ্ছিক)
                    .into(imageView, new Callback() {
                        @Override
                        public void onSuccess() {
                            Toast.makeText(MainActivity.this, "ইমেজ লোড সম্পন্ন", Toast.LENGTH_SHORT).show();
                        }

                        @Override
                        public void onError(Exception e) {
                            Toast.makeText(MainActivity.this, "লোড ব্যর্থ: " + e.getMessage(), Toast.LENGTH_SHORT).show();
                        }
                    });
        });
    }
}

Picasso-এর শक्तিশালী ফিচারগুলো

১. রিসাইজ এবং স্কেল টাইপ

Picasso.get()
    .load(url)
    .resize(300, 200)              // নির্দিষ্ট আকারে রিসাইজ (এস্পেক্ট রেশিও বজায় রাখে না)
    .resize(300, 200)              // বা
    .resizeDimen(R.dimen.width, R.dimen.height)
    .centerCrop()                  // কроп করে বাক্স পূরণ করুন (ImageView.ScaleType.CENTER_CROP)
    .centerInside()                // ইমেজ পুরো দেখান বাক্সের ভিতরে (CENTER_INSIDE)
    .fit()                         // ImageView-এর আকার অনুযায়ী ফিট করুন (লেআউট পাসের পর)
    .into(imageView);

২. রোটেশন

Picasso.get()
    .load(url)
    .rotate(90f)           // ৯০ ডিগ্রি ঘুরান
    .rotate(90f, 100f, 100f) // নির্দিষ্ট পিভট পয়েন্ট দিয়ে ঘুরান
    .into(imageView);

৩. ট্রান্সফরমেশন (কাস্টম)

// বৃত্তাকার ইমেজের জন্য
public class CircleTransform implements Transformation {
    @Override
    public Bitmap transform(Bitmap source) {
        int size = Math.min(source.getWidth(), source.getHeight());
        int x = (source.getWidth() - size) / 2;
        int y = (source.getHeight() - size) / 2;
        Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);
        Bitmap result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(result);
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        canvas.drawCircle(size / 2f, size / 2f, size / 2f, paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(squared, 0, 0, paint);
        if (squared != source) squared.recycle();
        return result;
    }

    @Override
    public String key() { return "circle"; }
}

// ব্যবহার
Picasso.get().load(url).transform(new CircleTransform()).into(imageView);

৪. ক্যাশিং পলিসি

Picasso.get()
    .load(url)
    .networkPolicy(NetworkPolicy.NO_CACHE)      // ক্যাশ এড়িয়ে নেটওয়ার্ক থেকে লোড
    .memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE) // মেমরি ক্যাশ বাইপাস
    .into(imageView);

// শুধু ক্যাশ থেকে (অফলাইন মোড)
Picasso.get()
    .load(url)
    .networkPolicy(NetworkPolicy.OFFLINE)
    .into(imageView, new Callback() {
        @Override public void onSuccess() {}
        @Override public void onError(Exception e) {
            // ক্যাশে নেই, অনলাইন লোড চেষ্টা করুন
            Picasso.get().load(url).into(imageView);
        }
    });

৫. লিস্ট/RecyclerView-এ ব্যবহার (ViewHolder প্যাটার্ন)

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    String url = items.get(position).getImageUrl();

    // ট্যাগ সেট করুন যাতে রিসাইকেলিং-এ পুরানো রিকোয়েস্ট ক্যাঞ্চেল হয়
    holder.itemView.setTag(url);

    Picasso.get()
            .load(url)
            .placeholder(R.drawable.placeholder)
            .fit()
            .centerCrop()
            .into(holder.imageView, new Callback() {
                @Override public void onSuccess() {}
                @Override public void onError(Exception e) {
                    // শুধু তখনই এরর দেখান যদি ট্যাগ এখনো মিলে
                    if (url.equals(holder.itemView.getTag())) {
                        holder.imageView.setImageResource(R.drawable.error_image);
                    }
                }
            });
}

৬. টার্গেট ব্যবহার করে বিটম্যাপ পাওয়া

Target target = new Target() {
    @Override
    public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
        // বিটম্যাপ পেয়ে গেলে - উদাহরণস্বরূপ শেয়ার করা বা সংরক্ষণ
        imageView.setImageBitmap(bitmap);
        // মনে রাখবেন: বিটম্যাপ রিসাইকেল হবে না, ম্যানুয়ালি ম্যানেজ করতে হবে
    }

    @Override
    public void onBitmapFailed(Exception e, Drawable errorDrawable) {}

    @Override
    public void onPrepareLoad(Drawable placeHolderDrawable) {}
};

// গুরুত্বপূর্ণ: টার্গেটকে স্ট্রং রেফারেন্স ধরে রাখুন (ফিল্ড হিসেবে), অথবা GC সংগ্রহ করবে
Picasso.get().load(url).into(target);

ধাপ ৪: AndroidManifest.xml-এ ইন্টারনেট পারমিশন

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="app.com.sample">

    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
</manifest>

Picasso vs Glide vs Coil - তুলনা

ফিচার Picasso Glide Coil (Kotlin)
সাইজ ~850 KB ~4.5 MB (with okhttp) ~1.5 MB
GIF সাপোর্ট সীমিত বहুত ভালো বহুত ভালো
ভিডিও থাম্বনেইল না হ্যাঁ হ্যাঁ
Kotlin DSL না (Extension দিয়ে) Extension API নেটিভ কোটলিন DSL
Jetpack Compose সীমিত সাপোর্ট করে বিল্ট-ইন

অ্যাপ্লিকেশন চালানোর পদ্ধতি

আপনার Android ডিভাইস কম্পিউটারের সাথে সংযুক্ত করুন। Android Studio-তে Run আইকনে ক্লিক করুন। "ইমেজ ডাউনলোড করুন" বাটনে ক্লিক করলে Pexels-এ থেকে ছবি লোড হবে।

Android-এ Picasso লাইব্রেরি ব্যবহার করে ইমেজ ডাউনলোড এবং প্রদর্শন

  1. Picasso লাইব্রেরি ব্যবহার করে অ্যান্ড্রয়েডে URL থেকে ImageView-এ ছবি লোড করার পদ্ধতি

  2. এন্ড্রয়েডে ViewFlipper ব্যবহার করার পদ্ধতি

  3. অ্যান্ড্রয়েডে দুটি ছবি ওভারলে (Overlay) করে ImageView-এ দেখানো

  4. Android-এ Glide ব্যবহার করে অ্যানিমেটেড GIF ছবি প্রদর্শন করা