অ্যান্ড্রয়েডে কীভাবে একটি বিটম্যাপের আকার পরিবর্তন করবেন?


336

আমার দূরবর্তী ডেটাবেস থেকে একটি বেস 64 encodedImageস্ট্রিংয়ের বিটম্যাপ নিয়েছি, ( বেস স্ট্রিংটি বেস 64 এর সাথে চিত্রিত করে):

profileImage = (ImageView)findViewById(R.id.profileImage);

byte[] imageAsBytes=null;
try {
    imageAsBytes = Base64.decode(encodedImage.getBytes());
} catch (IOException e) {e.printStackTrace();}

profileImage.setImageBitmap(
    BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length)
);

প্রোফাইল ইমেজ আমার ইমেজভিউ

ঠিক আছে, তবে ImageViewআমার লেআউটটি দেখানোর আগে আমাকে এই চিত্রটি পুনরায় আকার দিতে হবে । আমাকে এটির আকার পরিবর্তন করতে হবে 120x120।

কেউ আমাকে কোডটি এটির আকার দেওয়ার জন্য বলতে পারেন?

আমি যে উদাহরণগুলি পেয়েছি সেগুলি প্রাপ্ত বেস 64 স্ট্রিং বিটম্যাপে প্রয়োগ করা যায়নি।


উত্তর:


550

পরিবর্তন:

profileImage.setImageBitmap(
    BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length)

প্রতি:

Bitmap b = BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length)
profileImage.setImageBitmap(Bitmap.createScaledBitmap(b, 120, 120, false));

ধরুন আপনার কাছে বড় রেজোলিউশন ইমেজটি 1200x1200 বলে এবং আপনি এটি প্রদর্শন করার সময় এটি চিত্রের ভিউতে পূর্ণ হবে। আমি যদি এটি স্কেল করে 75% বলি এবং স্ক্রিনটি যাতে এটির আকারযুক্ত চিত্রটি সম্পূর্ণভাবে চিত্রের দৃশ্যে প্রদর্শিত হয় তবে এই জাতীয় পর্দার জন্য কী করা উচিত?
jxgn

5
ক্রিয়েস্কেলবিটম্যাপটি আমার গ্যালাক্সি ট্যাব 2 এ একটি আউট অফ মেমরি এক্সেপশন ফেলে দেয় যা আমার কাছে খুব অদ্ভুত কারণ যেহেতু প্রচুর স্মৃতি রয়েছে এবং অন্য কোনও বিশেষ অ্যাপ চলছে না। ম্যাট্রিক্স সমাধানটি যদিও কাজ করে work
লুডোভিচ

28
আমরা যদি অনুপাতটি সংরক্ষণ করতে চাই তবে ??
বাগগুলি

3
এর জন্য ডিপিআই স্কেলিংয়ের কী হবে? আমি মনে করি স্কেলড বিটম্যাপটি ডিভাইসের স্ক্রিনের উচ্চতা এবং প্রস্থের ভিত্তিতে হওয়া উচিত?
ডগ রে

2
মূল চিত্রটির অর্ধেকেরও বেশি চিত্র ডাউনস্কেল করতে বিটম্যাপ.ক্রিয়েটসেল্ডবিটম্যাপ () ব্যবহার করে, এলিয়াসিং শিল্পকর্ম তৈরি করতে পারে। আমি লিখেছিলাম এমন একটি পোস্ট আপনি একবার দেখে নিতে পারেন যেখানে আমি কিছু বিকল্প প্রস্তাব করি এবং মান এবং পারফরম্যান্সের তুলনা করি।
পেট্রাকিয়াস

288
import android.graphics.Matrix
public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight) {
    int width = bm.getWidth();
    int height = bm.getHeight();
    float scaleWidth = ((float) newWidth) / width;
    float scaleHeight = ((float) newHeight) / height;
    // CREATE A MATRIX FOR THE MANIPULATION
    Matrix matrix = new Matrix();
    // RESIZE THE BIT MAP
    matrix.postScale(scaleWidth, scaleHeight);

    // "RECREATE" THE NEW BITMAP
    Bitmap resizedBitmap = Bitmap.createBitmap(
        bm, 0, 0, width, height, matrix, false);
    bm.recycle();
    return resizedBitmap;
}

সম্পাদনা: @avechini দ্বারা প্রস্তাবিত হিসাবে, আমি bm.recycle();মেমরি ফাঁস জন্য যুক্ত করেছি দয়া করে নোট করুন যে ক্ষেত্রে যদি আপনি পূর্ববর্তী কোনও বিষয় অন্য কোনও উদ্দেশ্যে ব্যবহার করে থাকেন তবে সেই অনুযায়ী হ্যান্ডেল করুন।


6
আমি বিটম্যাপ.ক্রিয়েটসেল্ড বিটম্যাপ এবং এই ম্যাট্রিক্স পদ্ধতির উভয়ই চেষ্টা করেছি। আমি দেখতে পেয়েছি ম্যাট্রিক্স পদ্ধতির সাথে চিত্রটি আরও স্পষ্ট। আমি জানি না এটি সাধারণ কিনা বা কেবল কারণ আমি ফোনের পরিবর্তে সিমুলেটর ব্যবহার করছি। আমার মতো একই ঝামেলা করা লোকের জন্য কেবল একটি ইঙ্গিত।
আনসন ইয়াও

2
এখানেও আপনাকে আরও ভাল মেমরি পারফরম্যান্সের জন্য বিএম.আরসিচাল () যুক্ত করতে হবে
আভেছিনী

2
সমাধানের জন্য ধন্যবাদ, তবে প্যারামিটারগুলি পুনরায় সাজানো থাকলে এটি আরও ভাল হবে; public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight)। আমি এটি খুঁজে পেতে সময় একটি নরক ব্যয়। ; পি
আক্রমণাত্মক

1
দ্রষ্টব্য যে ম্যাট্রিক্সের জন্য সঠিক আমদানিটি হ'ল অ্যান্ড্রয়েড.গ্রাফিক্স M ম্যাট্রিক্স।
লেভ

11
এটি Bitmap.createScaledBitmap () কল করার সমান। দেখুন android.googlesource.com/platform/frameworks/base/+/refs/heads/...
BamsBamx

122

আপনার যদি ইতিমধ্যে একটি বিটম্যাপ থাকে তবে আপনি পুনরায় আকার দেওয়ার জন্য নিম্নলিখিত কোডটি ব্যবহার করতে পারেন:

Bitmap originalBitmap = <original initialization>;
Bitmap resizedBitmap = Bitmap.createScaledBitmap(
    originalBitmap, newWidth, newHeight, false);

1
@ বিগিনার আপনি যদি চিত্রটির আকার পরিবর্তন করেন তবে আপনি বিভিন্ন মাত্রার উপর ভিত্তি করে স্কেলিং করতে পারেন যা বিটম্যাপকে ভুল অনুপাতে রূপান্তরিত করে বা বিটম্যাপের কিছু তথ্য সরিয়ে দেয়।
জেনবুল্যান্স

আমি অনুপাতের ভিত্তিতে বিটম্যাপটিকে পুনরায় আকার দেওয়ার চেষ্টা করেছি, তবে তখন আমি এই ত্রুটিটি পেয়েছি। এর দ্বারা তৈরি: java.lang.Runটাইম এক্সসেপশন: ক্যানভাস: একটি পুনর্ব্যবহৃত বিটম্যাপ অ্যান্ড্রয়েড.গ্রাফিক্স.বিটম্যাপ @ 2291dd13 ব্যবহার করার চেষ্টা করছে
শিক্ষানবিস

আপনি যা করছেন তার উপর নির্ভর করে আপনার বিটম্যাপটিকে প্রতিটি আকার পরিবর্তন করুন ইতিমধ্যে স্মৃতিতে পুনর্ব্যবহারযোগ্য)।
জেনবুলেন্স

1
সঠিক .. আমি এটি চেষ্টা করেছিলাম এবং এটি এখন সঠিকভাবে কাজ করে। ধন্যবাদ
শিক্ষানবিশ

39

দিক অনুপাতের ভিত্তিতে স্কেল :

float aspectRatio = yourSelectedImage.getWidth() / 
    (float) yourSelectedImage.getHeight();
int width = 480;
int height = Math.round(width / aspectRatio);

yourSelectedImage = Bitmap.createScaledBitmap(
    yourSelectedImage, width, height, false);

প্রস্থ পরিবর্তনের বেস ইন্টাড হিসাবে উচ্চতা ব্যবহার করতে:

int height = 480;
int width = Math.round(height * aspectRatio);

24

দিকের অনুপাত বজায় রেখে একটি লক্ষ্য সর্বাধিক আকার এবং প্রস্থ সহ একটি বিটম্যাপ স্কেল করুন:

int maxHeight = 2000;
int maxWidth = 2000;    
float scale = Math.min(((float)maxHeight / bitmap.getWidth()), ((float)maxWidth / bitmap.getHeight()));

Matrix matrix = new Matrix();
matrix.postScale(scale, scale);

bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);

7

এই কোডটি চেষ্টা করে দেখুন:

BitmapDrawable drawable = (BitmapDrawable) imgview.getDrawable();
Bitmap bmp = drawable.getBitmap();
Bitmap b = Bitmap.createScaledBitmap(bmp, 120, 120, false);

আমি আশা করি এটি কার্যকর


7

কেউ এই পরিস্থিতিতে কীভাবে অনুপাত রক্ষা করবেন জিজ্ঞাসা করেছেন:

আপনি স্কেলিংয়ের জন্য যে ফ্যাক্টরটি ব্যবহার করছেন তা গণনা করুন এবং এটি উভয় মাত্রার জন্য ব্যবহার করুন। আসুন বলুন যে আপনি চান একটি চিত্র উচ্চতার পর্দার 20% হওয়া উচিত

int scaleToUse = 20; // this will be our percentage
Bitmap bmp = BitmapFactory.decodeResource(
    context.getResources(), R.drawable.mypng);
int sizeY = screenResolution.y * scaleToUse / 100;
int sizeX = bmp.getWidth() * sizeY / bmp.getHeight();
Bitmap scaled = Bitmap.createScaledBitmap(bmp, sizeX, sizeY, false);

স্ক্রিন রেজোলিউশন পাওয়ার জন্য আপনার এই সমাধানটি রয়েছে: পিক্সেলগুলিতে পর্দার মাত্রা পান


3

এটি চেষ্টা করুন: এই ফাংশনটি একটি বিটম্যাপকে আনুপাতিকভাবে আকার দেয়। যখন সর্বশেষ প্যারামিটারটি "এক্স" তে সেট করা থাকে তখন এটি newDimensionXorYনতুন প্রস্থ হিসাবে বিবেচিত হয় এবং যখন "ওয়াই" তে একটি নতুন উচ্চতা সেট করা হয়।

public Bitmap getProportionalBitmap(Bitmap bitmap, 
                                    int newDimensionXorY, 
                                    String XorY) {
    if (bitmap == null) {
        return null;
    }

    float xyRatio = 0;
    int newWidth = 0;
    int newHeight = 0;

    if (XorY.toLowerCase().equals("x")) {
        xyRatio = (float) newDimensionXorY / bitmap.getWidth();
        newHeight = (int) (bitmap.getHeight() * xyRatio);
        bitmap = Bitmap.createScaledBitmap(
            bitmap, newDimensionXorY, newHeight, true);
    } else if (XorY.toLowerCase().equals("y")) {
        xyRatio = (float) newDimensionXorY / bitmap.getHeight();
        newWidth = (int) (bitmap.getWidth() * xyRatio);
        bitmap = Bitmap.createScaledBitmap(
            bitmap, newWidth, newDimensionXorY, true);
    }
    return bitmap;
}

3
profileImage.setImageBitmap(
    Bitmap.createScaledBitmap(
        BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length), 
        80, 80, false
    )
);

3
  public Bitmap scaleBitmap(Bitmap mBitmap) {
        int ScaleSize = 250;//max Height or width to Scale
        int width = mBitmap.getWidth();
        int height = mBitmap.getHeight();
        float excessSizeRatio = width > height ? width / ScaleSize : height / ScaleSize;
         Bitmap bitmap = Bitmap.createBitmap(
                mBitmap, 0, 0,(int) (width/excessSizeRatio),(int) (height/excessSizeRatio));
        //mBitmap.recycle(); if you are not using mBitmap Obj
        return bitmap;
    }

আমার জন্য এটি ভাসা অতিরিক্ত সাইজরেটিও = প্রস্থ> উচ্চতা পুনরায় টাইপ করার পরে কাজ করেছিল? (ভাসা) ((ভাসা) প্রস্থ / (ভাসা) স্কেল সাইজ): (ভাসা) ((ভাসা) উচ্চতা / (ভাসা) স্কেল সাইজ);
সিএসবি

3
public static Bitmap resizeBitmapByScale(
            Bitmap bitmap, float scale, boolean recycle) {
        int width = Math.round(bitmap.getWidth() * scale);
        int height = Math.round(bitmap.getHeight() * scale);
        if (width == bitmap.getWidth()
                && height == bitmap.getHeight()) return bitmap;
        Bitmap target = Bitmap.createBitmap(width, height, getConfig(bitmap));
        Canvas canvas = new Canvas(target);
        canvas.scale(scale, scale);
        Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG);
        canvas.drawBitmap(bitmap, 0, 0, paint);
        if (recycle) bitmap.recycle();
        return target;
    }
    private static Bitmap.Config getConfig(Bitmap bitmap) {
        Bitmap.Config config = bitmap.getConfig();
        if (config == null) {
            config = Bitmap.Config.ARGB_8888;
        }
        return config;
    }


2

যে কোনও ডিসপ্লে আকারের ভিত্তিতে বিটম্যাপ পুনরায় আকার দিন

public Bitmap bitmapResize(Bitmap imageBitmap) {

    Bitmap bitmap = imageBitmap;
    float heightbmp = bitmap.getHeight();
    float widthbmp = bitmap.getWidth();

    // Get Screen width
    DisplayMetrics displaymetrics = new DisplayMetrics();
    this.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
    float height = displaymetrics.heightPixels / 3;
    float width = displaymetrics.widthPixels / 3;

    int convertHeight = (int) hight, convertWidth = (int) width;

    // higher
    if (heightbmp > height) {
        convertHeight = (int) height - 20;
        bitmap = Bitmap.createScaledBitmap(bitmap, convertWidth,
                convertHighet, true);
    }

    // wider
    if (widthbmp > width) {
        convertWidth = (int) width - 20;
        bitmap = Bitmap.createScaledBitmap(bitmap, convertWidth,
                convertHeight, true);
    }

    return bitmap;
}

1

যদিও গৃহীত উত্তরটি সঠিক, এটি Bitmapএকই पहलू অনুপাত রেখে আকার পরিবর্তন করে না । আপনি যদি Bitmapএকই দিকটি অনুপাত রেখে পুনরায় আকার দেওয়ার কোনও পদ্ধতির সন্ধান করছেন তবে নীচের ইউটিলিটি ফাংশনটি ব্যবহার করতে পারেন। ফাংশনের ব্যবহারের বিশদ এবং ব্যাখ্যা এই লিঙ্কটিতে উপস্থিত রয়েছে ।

public static Bitmap resizeBitmap(Bitmap source, int maxLength) {
       try {
           if (source.getHeight() >= source.getWidth()) {
               int targetHeight = maxLength;
               if (source.getHeight() <= targetHeight) { // if image already smaller than the required height
                   return source;
               }

               double aspectRatio = (double) source.getWidth() / (double) source.getHeight();
               int targetWidth = (int) (targetHeight * aspectRatio);

               Bitmap result = Bitmap.createScaledBitmap(source, targetWidth, targetHeight, false);
               if (result != source) {
               }
               return result;
           } else {
               int targetWidth = maxLength;

               if (source.getWidth() <= targetWidth) { // if image already smaller than the required height
                   return source;
               }

               double aspectRatio = ((double) source.getHeight()) / ((double) source.getWidth());
               int targetHeight = (int) (targetWidth * aspectRatio);

               Bitmap result = Bitmap.createScaledBitmap(source, targetWidth, targetHeight, false);
               if (result != source) {
               }
               return result;

           }
       }
       catch (Exception e)
       {
           return source;
       }
   }

0
/**
 * Kotlin method for Bitmap scaling
 * @param bitmap the bitmap to be scaled
 * @param pixel  the target pixel size
 * @param width  the width
 * @param height the height
 * @param max    the max(height, width)
 * @return the scaled bitmap
 */
fun scaleBitmap(bitmap:Bitmap, pixel:Float, width:Int, height:Int, max:Int):Bitmap {
    val scale = px / max
    val h = Math.round(scale * height)
    val w = Math.round(scale * width)
    return Bitmap.createScaledBitmap(bitmap, w, h, true)
  }

0

দিক অনুপাত রেখে,

  public Bitmap resizeBitmap(Bitmap source, int width,int height) {
    if(source.getHeight() == height && source.getWidth() == width) return source;
    int maxLength=Math.min(width,height);
    try {
        source=source.copy(source.getConfig(),true);
        if (source.getHeight() <= source.getWidth()) {
            if (source.getHeight() <= maxLength) { // if image already smaller than the required height
                return source;
            }

            double aspectRatio = (double) source.getWidth() / (double) source.getHeight();
            int targetWidth = (int) (maxLength * aspectRatio);

            return Bitmap.createScaledBitmap(source, targetWidth, maxLength, false);
        } else {

            if (source.getWidth() <= maxLength) { // if image already smaller than the required height
                return source;
            }

            double aspectRatio = ((double) source.getHeight()) / ((double) source.getWidth());
            int targetHeight = (int) (maxLength * aspectRatio);

            return Bitmap.createScaledBitmap(source, maxLength, targetHeight, false);

        }
    }
    catch (Exception e)
    {
        return source;
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.