বিটম্যাপের অ্যান্ড্রয়েড ক্রপ সেন্টার


150

আমার বিটম্যাপ রয়েছে যা স্কোয়ার বা আয়তক্ষেত্র। আমি সংক্ষিপ্ত দিকটি গ্রহণ করি এবং এরকম কিছু করি:

int value = 0;
if (bitmap.getHeight() <= bitmap.getWidth()) {
    value = bitmap.getHeight();
} else {
    value = bitmap.getWidth();
}

Bitmap finalBitmap = null;
finalBitmap = Bitmap.createBitmap(bitmap, 0, 0, value, value);

তারপরে আমি এটি ব্যবহার করে এটি 144 x 144 বিটম্যাপে স্কেল করব:

Bitmap lastBitmap = null;
lastBitmap = Bitmap.createScaledBitmap(finalBitmap, 144, 144, true);

সমস্যাটি হ'ল এটি মূল বিটম্যাপের উপরের বাম কোণটি কেটে দেয়, বিটম্যাপের কেন্দ্রে ক্রপ করার কোড রয়েছে কারও কাছে?

উত্তর:


354

এখানে চিত্র বর্ণনা লিখুন

এটি দিয়ে অর্জন করা যেতে পারে: বিটম্যাপ ক্রেটবিটম্যাপ (উত্স, এক্স, ওয়াই, প্রস্থ, উচ্চতা)

if (srcBmp.getWidth() >= srcBmp.getHeight()){

  dstBmp = Bitmap.createBitmap(
     srcBmp, 
     srcBmp.getWidth()/2 - srcBmp.getHeight()/2,
     0,
     srcBmp.getHeight(), 
     srcBmp.getHeight()
     );

}else{

  dstBmp = Bitmap.createBitmap(
     srcBmp,
     0, 
     srcBmp.getHeight()/2 - srcBmp.getWidth()/2,
     srcBmp.getWidth(),
     srcBmp.getWidth() 
     );
}

1
উত্তরটি সম্পাদিত করে যাতে আসল গন্তব্য বিটম্যাপটি একটি বর্গক্ষেত্র।
জোরাম ভ্যান ডেন বোয়েজেম

1
@ লুমিস: আপনি কেন পুনরায় সংশোধন 3 করলেন? এটি একটি বৈধ সঠিক বলে মনে হয়েছিল। আপনার বর্তমান সংস্করণটি সঠিক সূচনা পয়েন্ট তৈরি করে তবে তারপরে খুব দীর্ঘ দিকের অংশটি অন্তর্ভুক্ত করে। উদাহরণস্বরূপ একটি 100x1000চিত্র দেওয়া আপনি একটি চিত্র ফিরে পেতে 100x550
গুয়ানতে

ধন্যবাদ, আপনি ঠিক বলেছেন, ফর্ম্যাটটি বিটম্যাপ.ক্রেটবিটম্যাপ (উত্স, এক্স, ওয়াই, প্রস্থ, উচ্চতা)
লুমিস

11
অন্তর্নির্মিত থাম্বনেইল ইউটিস.অ্যাক্সট্রাক্ট থাম্বনেল () পদ্ধতিটি ব্যবহার সম্পর্কে আমার উত্তর দেখুন। চাকা পুনরুদ্ধার কেন ??? stackoverflow.com/a/17733530/1103584
DiscDev

1
এই দ্রষ্টব্যটি একটি ক্যানভাস তৈরি করার চেয়ে কম এবং এরপরে এটি একটি আঁকতে আঁকতে। এটি থাম্বনেইলটিলস সলিউশন (যা কীভাবে স্কেল করতে হবে তা নির্ধারণের জন্য নমুনা আকার গণনা করে) এর চেয়ে কম প্রক্রিয়াজাতকরণও করে।
ইঙ্ক্রাশ

319

উপরের উত্তরগুলির বেশিরভাগই এটি করার জন্য একটি উপায় সরবরাহ করে, এটি সম্পাদন করার জন্য ইতিমধ্যে একটি অন্তর্নির্মিত উপায় রয়েছে এবং এটি কোডের 1 লাইন ( ThumbnailUtils.extractThumbnail())

int dimension = getSquareCropDimensionForBitmap(bitmap);
bitmap = ThumbnailUtils.extractThumbnail(bitmap, dimension, dimension);

...

//I added this method because people keep asking how 
//to calculate the dimensions of the bitmap...see comments below
public int getSquareCropDimensionForBitmap(Bitmap bitmap)
{
    //use the smallest dimension of the image to crop to
    return Math.min(bitmap.getWidth(), bitmap.getHeight());
}

আপনি যদি বিটম্যাপ অবজেক্টটি পুনর্ব্যবহার করতে চান তবে আপনি এমন বিকল্পগুলি পাস করতে পারেন যা এটি তৈরি করে:

bitmap = ThumbnailUtils.extractThumbnail(bitmap, dimension, dimension, ThumbnailUtils.OPTIONS_RECYCLE_INPUT);

থেকে: থাম্বনেইল ইউটিলেস ডকুমেন্টেশন

পাবলিক স্ট্যাটিক বিটম্যাপ এক্সট্র্যাক্ট থাম্বনেল (বিটম্যাপ সোর্স, ইনট প্রস্থ, ইনট উচ্চতা)

এপিআই স্তর 8 এ যুক্ত করা পছন্দসই আকারের কেন্দ্রিক বিটম্যাপ তৈরি করে।

পরামিতি উত্স মূল বিটম্যাপ উত্স প্রস্থ টার্গেট প্রস্থ দৈর্ঘ্য উচ্চতা লক্ষ্যমাত্রা

গ্রহণযোগ্য উত্তরটি ব্যবহার করার সময় আমি কখনও কখনও মেমরির ত্রুটিগুলি থেকে মুক্তি পেয়েছিলাম এবং থাম্বনেইল ইউটিসগুলি ব্যবহার করে আমার জন্য এই সমস্যাগুলি সমাধান করে। এছাড়াও, এটি অনেক বেশি ক্লিনার এবং আরও পুনরায় ব্যবহারযোগ্য।


6
+1 আমি মনে করি আপনাকে এই কোডটি উন্নত করতে হবে এবং 400px ব্যবহার করার পরিবর্তে, উপরের মূল পোস্টের বিকল্প সরবরাহ করার জন্য, সংক্ষিপ্ততম বিএমপির আকারটি পাস করুন। তবে এটি আমাদের নজরে আনার জন্য আপনাকে ধন্যবাদ, এটি একটি খুব কার্যকর কার্য বলে মনে হচ্ছে। করুণা আমি এর আগে দেখিনি ...
লুমিস

ঠিক আছে, আমি একটি
দৃ concrete়

4
@ ডিস্কডেভ - এটি পুরো সাইটের সবচেয়ে কার্যকরী উত্তর হতে হবে। সিরিয়াসলি। এটি অ্যান্ড্রয়েড প্রশ্নগুলির সাথে অদ্ভুত - আপনি সহজ স্পষ্ট উত্তরটি খুঁজে পাওয়ার আগে প্রায় দুই ঘন্টা অনুসন্ধান করতে পারেন। কীভাবে আপনাকে ধন্যবাদ দিতে হবে তা জানেন না। পথে অনুগ্রহ!
ফ্যাটি

2
আপনি পুরানো বিটম্যাপটি পুনরায় ব্যবহার করতে, এমনকি কিছুটা আলাদা ফাংশনও ব্যবহার করতে পারেন: = থাম্বনেইল ইউটিস.অ্যাক্সট্রাক্ট থাম্বনেল (বিটম্যাপ, প্রস্থ, উচ্চতা, থাম্বনেইল
অ্যান্ড্রয়েড বিকাশকারী

1
অ্যান্ড্রয়েড প্রশ্নের জন্য আমি এ পর্যন্ত সবচেয়ে শক্তিশালী উত্তর। অ্যান্ড্রয়েডে বিটম্যাপে স্কেল / ক্রপ / ডাউনস্কেল / আকার পরিবর্তন এবং আরও কীভাবে 20 টি বিভিন্ন সমাধানের মতো দেখেছি। সমস্ত উত্তর পৃথক। এবং এটি এক মাত্র 1 লাইন নেয় এবং প্রত্যাশার মতো ঠিক কাজ করে। ধন্যবাদ.
অ্যালেক্স সোরোকোলেটোভ

12

আপনি কি এটা থেকে বিবেচনা করেছেন layout.xml? তুমি তোমার জন্য সেট পারে ScaleType করতে এবং ইমেজ মাত্রা নির্ধারণ করে ভিতরে ।ImageViewandroid:scaleType="centerCrop"ImageViewlayout.xml


আমি নিম্নলিখিত ওপেনএলএল রেন্ডারারের ত্রুটির সাথে এই ধারণার চেষ্টা করেছি: "টেক্সচারে আপলোড করার জন্য বিটম্যাপটি খুব বড় (2432x4320, সর্বোচ্চ = 4096x4096)" সুতরাং, আমি অনুমান করছি 4320 উচ্চতা প্রক্রিয়া করা যায় না।
গ্রেগএম

1
অবশ্যই এটি একটি সঠিক উত্তর এবং প্রশ্নের সঠিক উত্তর দেয় নিখুঁত! বড় চিত্রগুলির জন্য চিত্রের মান / আকারের অনুকূলকরণ ... ভাল, এটি অন্যরকম প্রশ্ন!
আইচলোস

@ আইচলস সম্ভবত আপনি যা খুঁজছিলেন তা পেয়েছেন তবে এটি আসল প্রশ্নের উত্তর দেয় না। মূল প্রশ্নটি ম্যানুয়ালি ক্যানভাসে রেন্ডারিংয়ের বিষয়ে ছিল .. আসলে আমি নিশ্চিত না যে কারও কোনও ফটো ক্রপ করার প্রথম প্রচেষ্টাটি ম্যানুয়ালি একটি ক্যানভাসে রেন্ডারিং হবে, তবে ওহে, ভাল যে আপনি এখানে একটি সমাধান পেয়েছেন :)
মিলোসমনস

পছন্দ করেছেন সম্ভবত এটির মাধ্যমে ব্যবহারকারী নিজেই কেন্দ্রে ফসলের সমস্যাটির কাছে যাওয়ার চেষ্টা করেছিলেন। এটি সবই মূল ব্যবহারকারীর সঠিক প্রয়োজনের উপর নির্ভর করে।
ইচলোস

9

আপনি নিম্নলিখিত কোড ব্যবহার করতে পারেন যা আপনার সমস্যার সমাধান করতে পারে।

Matrix matrix = new Matrix();
matrix.postScale(0.5f, 0.5f);
Bitmap croppedBitmap = Bitmap.createBitmap(bitmapOriginal, 100, 100,100, 100, matrix, true);

সর্বোপরি পদ্ধতিতে ফসলের আগে চিত্রের পোস্টস্কলিং করুন, যাতে আপনি ওওমের ত্রুটি না পেয়ে ক্রপযুক্ত চিত্রের সাথে সেরা ফলাফল পেতে পারেন।

আরও বিশদ জন্য আপনি এই ব্লগ উল্লেখ করতে পারেন


1
ই / অ্যান্ড্রয়েডআরটাইম (30010): এর কারণ: java.lang.IllegalArgumentException: x + প্রস্থ অবশ্যই <= বিটম্যাপ.উইথথ () হতে হবে এবং এটি 4 গুণ 100 পিক্সের কারণে
স্টান

9

এখানে আরও একটি সম্পূর্ণ স্নিপেট যা স্বেচ্ছাসেবী মাত্রার একটি [বিটম্যাপ] এর কেন্দ্রে আউট করে এবং ফলাফলটিকে আপনার কাঙ্ক্ষিত [IMAGE_SIZE] এর আকার দেয় । সুতরাং আপনি সর্বদা একটি নির্দিষ্ট আকারের চিত্র কেন্দ্রের একটি [ক্রপযুক্ত বিটম্যাপ] স্কেল করা বর্গ পাবেন। থাম্বনেইলিং এবং যেমন জন্য আদর্শ।

এটি অন্যান্য সমাধানগুলির আরও সম্পূর্ণ সমন্বয়।

final int IMAGE_SIZE = 255;
boolean landscape = bitmap.getWidth() > bitmap.getHeight();

float scale_factor;
if (landscape) scale_factor = (float)IMAGE_SIZE / bitmap.getHeight();
else scale_factor = (float)IMAGE_SIZE / bitmap.getWidth();
Matrix matrix = new Matrix();
matrix.postScale(scale_factor, scale_factor);

Bitmap croppedBitmap;
if (landscape){
    int start = (tempBitmap.getWidth() - tempBitmap.getHeight()) / 2;
    croppedBitmap = Bitmap.createBitmap(tempBitmap, start, 0, tempBitmap.getHeight(), tempBitmap.getHeight(), matrix, true);
} else {
    int start = (tempBitmap.getHeight() - tempBitmap.getWidth()) / 2;
    croppedBitmap = Bitmap.createBitmap(tempBitmap, 0, start, tempBitmap.getWidth(), tempBitmap.getWidth(), matrix, true);
}

8

সম্ভবত এখন পর্যন্ত সবচেয়ে সহজ সমাধান:

public static Bitmap cropCenter(Bitmap bmp) {
    int dimension = Math.min(bmp.getWidth(), bmp.getHeight());
    return ThumbnailUtils.extractThumbnail(bmp, dimension, dimension);
}

আমদানি:

import android.media.ThumbnailUtils;
import java.lang.Math;
import android.graphics.Bitmap;

3

@ উইলস্টিল সমাধানটি সংশোধন করতে:

if (landscape){
                int start = (tempBitmap.getWidth() - tempBitmap.getHeight()) / 2;
                croppedBitmap = Bitmap.createBitmap(tempBitmap, start, 0, tempBitmap.getHeight(), tempBitmap.getHeight(), matrix, true);
            } else {
                int start = (tempBitmap.getHeight() - tempBitmap.getWidth()) / 2;
                croppedBitmap = Bitmap.createBitmap(tempBitmap, 0, start, tempBitmap.getWidth(), tempBitmap.getWidth(), matrix, true);
            }

এটি উইলস্টিল সমাধানের সমাধান। এই ক্ষেত্রে, টেম্প বিটম্যাপটি মূল (আনলটার্টেড) বিটম্যাপ বা নিজেই একটি অনুলিপি।
ইয়ামান

1
public static Bitmap resizeAndCropCenter(Bitmap bitmap, int size, boolean recycle) {
    int w = bitmap.getWidth();
    int h = bitmap.getHeight();
    if (w == size && h == size) return bitmap;
    // scale the image so that the shorter side equals to the target;
    // the longer side will be center-cropped.
    float scale = (float) size / Math.min(w,  h);
    Bitmap target = Bitmap.createBitmap(size, size, getConfig(bitmap));
    int width = Math.round(scale * bitmap.getWidth());
    int height = Math.round(scale * bitmap.getHeight());
    Canvas canvas = new Canvas(target);
    canvas.translate((size - width) / 2f, (size - height) / 2f);
    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;
}

1
public Bitmap getResizedBitmap(Bitmap bm) {
    int width = bm.getWidth();
    int height = bm.getHeight();

    int narrowSize = Math.min(width, height);
    int differ = (int)Math.abs((bm.getHeight() - bm.getWidth())/2.0f);
    width  = (width  == narrowSize) ? 0 : differ;
    height = (width == 0) ? differ : 0;

    Bitmap resizedBitmap = Bitmap.createBitmap(bm, width, height, narrowSize, narrowSize);
    bm.recycle();
    return resizedBitmap;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.