অ্যান্ড্রয়েড: একটি অঙ্কনযোগ্য বা পটভূমির চিত্র স্কেল করতে চান?


134

একটি বিন্যাসে আমি পৃষ্ঠা তৈরি হয়ে গেলে বরাদ্দকৃত স্থানটিতে ব্যাকগ্রাউন্ড চিত্রটি (তার দিক অনুপাত রেখে) স্কেল করতে চাই। এটি করার জন্য কারও কি ধারণা আছে?

আমি ক্লিপিং এবং ফিলিংয়ের জন্য সেট করতে layout.setBackgroundDrawable()একটি ব্যবহার করছি , তবে স্কেলিংয়ের কোনও বিকল্প দেখতে পাচ্ছি না।BitmapDrawable()gravity


আমার এই সমস্যাটি ছিল এবং আঙ্কের প্রস্তাবিত পরিবর্তনের সাথে ডুয়েবো-র পরামর্শ অনুসরণ করে ফিটনেসওয়ানকে ফিটসেন্টারে পরিবর্তিত করেছিলাম। ভাল কাজ করেছেন।

উত্তর:


90

ব্যাকগ্রাউন্ড ইমেজ স্কেলিং কাস্টমাইজ করতে এই জাতীয় উত্স তৈরি করুন:

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:gravity="center"
    android:src="@drawable/list_bkgnd" />

তারপরে এটি ব্যাকগ্রাউন্ড হিসাবে ব্যবহার করা হলে সেই দৃশ্যকে কেন্দ্র করে নেওয়া হবে। এছাড়াও অন্যান্য পতাকা রয়েছে: http://developer.android.com/guide/topics/resources/drawable-resource.html


6
আমি বিটম্যাপটি ব্যবহার করার চেষ্টা করেছি তবে চিত্রটি কেবল কেন্দ্রিক, স্যাম জিজ্ঞাসা করার মতো আকারে নয়। আমি যখন ইমেজভিউটি ব্যবহার করি তখন এটি সুন্দর করে কাজ করে, কোনও গন্ধ / ঝগড়া হয় না। (এনবি: আমি আমার ক্ষেত্রেও স্ক্রোল করছি না)) চিত্রটি স্কেল করার জন্য আমি কী দিয়ে বিটম্যাপটি বাড়িয়ে তুলব?
জো

7
সম্ভাব্য মানগুলি: "শীর্ষ" | "নীচে" | "বাম" | "ডান" | "সেন্টার_ভার্টিকাল" | "ভরাট_ভারটিকাল" | "কেন্দ্র_হরিজন্টাল" | "ফিল_হরিজন্টাল" | "কেন্দ্র" | "ভরাট" | "ক্লিপ_ভারটিকাল" | "ক্লিপ_হরিজন্টাল"
আলেক্স এন।

30
এই পরামিতিগুলির কোনও বিটম্যাপকে স্কেল করে না, এপস রেশনটি রেখে, তাই উত্তরটি ভুল।
মালাকিয়াজ

7
প্রিয় মালাচিয়াজ, 'কেন্দ্র' দিক অনুপাতকে সম্মান করে। তবে এটি চিত্রটি নীচে স্কেল করবে না। যার অর্থ এটি ব্যবহার করা কিছুটা বিপদজনক বৈশিষ্ট্য। লক্ষ্যটির রেজোলিউশনের উপর নির্ভর করে আপনি কখনই জানেন না যে জিনিসটি কী পরিমাণে মাপা হবে তা ঠিক বেরিয়ে আসবে। গুগল দ্বারা আর একটি অর্ধ assed সমাধান।

2
স্কেলটাইপ বৈশিষ্ট্য যুক্ত করার একটি উপায় আছে?
ademar111190

57

আপনি যা চান ঠিক তেমন চেষ্টা করার চেষ্টা করেননি, তবে আপনি ব্যবহার করে একটি চিত্রদর্শন স্কেল করতে পারেন android:scaleType="fitXY"
এবং আপনি চিত্রভিউ যে আকারে দেবেন তা মাপতে এটি আকারযুক্ত হবে।

সুতরাং আপনি আপনার বিন্যাসের জন্য একটি ফ্রেমলাউট তৈরি করতে পারেন, এর ভিতরে চিত্রকল্পটি রেখেছিলেন এবং তারপরে ফ্রেম-লেআউটে আপনার অন্য যে কোনও সামগ্রীর প্রয়োজন যেমন ডাব্লু / স্বচ্ছ পটভূমি।

<FrameLayout  
android:layout_width="fill_parent" android:layout_height="fill_parent">

  <ImageView 
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:src="@drawable/back" android:scaleType="fitXY" />

  <LinearLayout>your views</LinearLayout>
</FrameLayout>

1
এটি কি কোনও সারফেসে করা সম্ভব? যদি তা না হয় তবে আমি ফ্রেম-লেআউট ব্যবহার করে (একটি রেকর্ডার অ্যাপের জন্য) পূর্বরূপ প্রদর্শন করতে পারি?
নমরাথা

1
@ ডুয়েবো: আপনি কি চেষ্টা করেছেন? এটি আমার পক্ষে কাজ করছে বলে মনে হয় না।
স্পিড প্লেন 19

3
একের পরিবর্তে দুটি ইউআই উপাদান ব্যবহার করা হ্রাস করা বিশেষত তালিকার ভিউয়ের মতো ব্যস্ত উপাদানগুলির জন্য একটি খারাপ ধারণা। সম্ভবত আপনি স্ক্রোল করার সময় সমস্যায় পড়বেন। যথাযথ সমাধান: স্ট্যাকওভারফ্লো.com
এলেক্স এন।

আমি ফিট সেন্টার এবং সেন্টারক্রপের স্কেল টাইপ চেষ্টা করেছি (বিভিন্ন ঘনত্বের জন্য অঙ্কনযোগ্য / চিত্রের কয়েকটি পরিবর্তনের সাথে) এবং এটি কার্যকর হয়েছে! হয় স্কেল টাইপ আমার জন্য জ্ঞান তৈরি - ইমেজ উপর ভিত্তি করে ব্যক্তিগত পছন্দ বেশি, আমি সন্দেহ। নোট করুন যে আমি ফ্রেম-লেআউটের পরিবর্তে মার্জ ব্যবহার করেছি এবং আমার বিশেষ ক্ষেত্রে কোনও স্ক্রলিং নেই।
জো

2
সেন্টারসাইডটি যথাযথ, ফিটএক্সওয়াই নয়, কারণ ফিট এক্সওয়াইজে চিত্রের অনুপাতটি রাখে না
মালাচিয়াজ

35

অঙ্কনযোগ্য থেকে এটি করার একটি সহজ উপায় রয়েছে:

your_drawable.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

    <item android:drawable="@color/bg_color"/>
    <item>
        <bitmap
            android:gravity="center|bottom|clip_vertical"
            android:src="@drawable/your_image" />
    </item>

</layer-list>

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

অন্য উপায়টি হ'ল কেবল একটি বিন্যাস তৈরি করা হবে, যেখানে আপনি একটি ব্যবহার করবেন ImageViewএবং এটি সেট scaleTypeকরবেন fitCenter


2
এই সমাধানটি অবশ্যই আমি আমার থিমের পটভূমির সম্পত্তিটি প্রতিস্থাপন করতে এবং ভিউতে ট্যাবগুলি থাকা বা না থাকাতে চিত্রের স্কেল আলাদাভাবে এড়াতে দীর্ঘ সময় খুঁজছিলাম। এটি ভাগ করে নেওয়ার জন্য ধন্যবাদ।
বিবু

1
এটি ত্রুটি দেখায়:error: <item> must have a 'name' attribute.
দিমিত্রি

thx @lonutNegru, আমার দিন বাঁচানোর জন্য +1 :)
রবি ভানিয়া

18

ব্যবহারের অনুপাত আপনি রাখতে android:scaleType=fitCenterবা fitStartব্যবহার ইত্যাদি fitXYচিত্রের আসল আকৃতি অনুপাত রাখা হবে না!

নোট করুন srcএটি ব্যাকগ্রাউন্ড চিত্রের জন্য নয়, কেবল একটি গুনযুক্ত চিত্রের জন্য কাজ করে ।


18

বিন্যাসে পটভূমি আকার হিসাবে চিত্র ব্যবহার করুন:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <ImageView
        android:id="@+id/imgPlaylistItemBg"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:adjustViewBounds="true"
        android:maxHeight="0dp"
        android:scaleType="fitXY"
        android:src="@drawable/img_dsh" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >


    </LinearLayout>

</FrameLayout>

ধন্যবাদ! এছাড়াও android:scaleType="centerCrop"কাজ করে।
শীতলমাইন্ড

5

আপনি যখন setBackgroundDrawableপদ্ধতিটি ব্যবহার করে কোনও চিত্রকল্পের অঙ্কনযোগ্য সেট করবেন তখন চিত্রটি সর্বদা পরিমাপযোগ্য হবে। adjustViewBoundsবা পৃথক হিসাবে পরামিতি ScaleTypesকেবল অগ্রাহ্য করা হবে। আমি যে দিকটি অনুপাত পেয়েছি তা ImageViewরক্ষার একমাত্র সমাধান হ'ল আপনার অঙ্কনযোগ্য লোড করার পরে পুনরায় আকার দেওয়া । এখানে আমি ব্যবহার করেছি কোড স্নিপেট:

// bmp is your Bitmap object
int imgHeight = bmp.getHeight();
int imgWidth = bmp.getWidth();
int containerHeight = imageView.getHeight();
int containerWidth = imageView.getWidth();
boolean ch2cw = containerHeight > containerWidth;
float h2w = (float) imgHeight / (float) imgWidth;
float newContainerHeight, newContainerWidth;

if (h2w > 1) {
    // height is greater than width
    if (ch2cw) {
        newContainerWidth = (float) containerWidth;
        newContainerHeight = newContainerWidth * h2w;
    } else {
        newContainerHeight = (float) containerHeight;
        newContainerWidth = newContainerHeight / h2w;
    }
} else {
    // width is greater than height
    if (ch2cw) {
        newContainerWidth = (float) containerWidth;
        newContainerHeight = newContainerWidth / h2w; 
    } else {
        newContainerWidth = (float) containerHeight;
        newContainerHeight = newContainerWidth * h2w;       
    }
}
Bitmap copy = Bitmap.createScaledBitmap(bmp, (int) newContainerWidth, (int) newContainerHeight, false);
imageView.setBackgroundDrawable(new BitmapDrawable(copy));
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
imageView.setLayoutParams(params);
imageView.setMaxHeight((int) newContainerHeight);
imageView.setMaxWidth((int) newContainerWidth);

কোডে উপরে snippet হয় BMP বিটম্যাপ বস্তু প্রদর্শন করা হয় এবং imageView হয় ImageViewবস্তুর

একটি লক্ষণীয় গুরুত্বপূর্ণ বিষয় হ'ল বিন্যাসের পরামিতিগুলির পরিবর্তন । এটি প্রয়োজনীয় কারণ setMaxHeightএবং setMaxWidthপ্রস্থ এবং উচ্চতাটি পিতা-মাতাকে পূরণ করার জন্য নয়, বিষয়বস্তু মোড়কে সংজ্ঞায়িত করা হলে কেবল তাত্পর্য হবে। অন্যদিকে পূরণ করুন পিতামাতার শুরুতে পছন্দসই সেটিংস, কারণ অন্যথায় containerWidthএবং containerHeightউভয়ের উভয়েরই মান 0 এর সমান হবে So সুতরাং, আপনার লেআউট ফাইলে আপনার চিত্রকল্পের জন্য এই জাতীয় কিছু থাকবে:

...
<ImageView android:id="@+id/my_image_view"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"/>
...

4

এটি সর্বাধিক পারফরম্যান্ট সমাধান নয়, তবে পটভূমির পরিবর্তে কারও পরামর্শ অনুসারে আপনি ফ্রেমলআউট বা রিলেটিভলআউট তৈরি করতে পারেন এবং চিত্রগ্রাহকে সিউডো ব্যাকগ্রাউন্ড হিসাবে ব্যবহার করতে পারেন - অন্যান্য উপাদানগুলি এর উপরে অবস্থানে থাকবে:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="match_parent"
    android:layout_width="match_parent">

    <ImageView
        android:id="@+id/ivBackground"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:scaleType="fitStart"
        android:src="@drawable/menu_icon_exit" />

    <Button
        android:id="@+id/bSomeButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="61dp"
        android:layout_marginTop="122dp"
        android:text="Button" />

</RelativeLayout>

ইমেজভিউয়ের সমস্যাটি হ'ল কেবল স্কেলটাইপগুলি উপলব্ধ: সেন্টার, সেন্ট সেন্ট্রোক, সেন্ট সেন্টিনসাইড, এফআইসেন্টার, এফআইএনএন্ড, এফআইএসটিআরটি, এফআইএসএক্সওয়াই, ম্যাট্রিক্স ( http://etcodehome.blogspot.de/2011/05/android-imageview-scaletype-sams )

এবং কিছু ক্ষেত্রে "ব্যাকগ্রাউন্ড চিত্রটি স্কেল করতে (তার দিকের অনুপাত রেখে)" যখন আপনি কোনও চিত্র পুরো পর্দাটি পূরণ করতে চান (উদাহরণস্বরূপ পটভূমি চিত্র) এবং স্ক্রিনের দিক অনুপাত চিত্রের চেয়ে আলাদা হয়, প্রয়োজনীয় স্কেল টাইপটি দয়ালু TOP_CROP এর, কারণ:

CENTER_CROP চিত্রের দৃশ্যের উপরের প্রান্তে শীর্ষ প্রান্তটি প্রান্তিককরণের পরিবর্তে ছোট আকারের চিত্রটিকে কেন্দ্র করে এবং FIT_START স্ক্রিনের উচ্চতার সাথে ফিট করে এবং প্রস্থটি পূরণ করে না। এবং ব্যবহারকারী হিসাবে আনেকে লক্ষ্য করা গেছে যে FIT_XY দিক অনুপাত রাখে না।

আনন্দের সাথে কেউ TOP_CROP সমর্থন করতে ইমেজভিউ বাড়িয়েছে

public class ImageViewScaleTypeTopCrop extends ImageView {
    public ImageViewScaleTypeTopCrop(Context context) {
        super(context);
        setup();
    }

    public ImageViewScaleTypeTopCrop(Context context, AttributeSet attrs) {
        super(context, attrs);
        setup();
    }

    public ImageViewScaleTypeTopCrop(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setup();
    }

    private void setup() {
        setScaleType(ScaleType.MATRIX);
    }

    @Override
    protected boolean setFrame(int frameLeft, int frameTop, int frameRight, int frameBottom) {

        float frameWidth = frameRight - frameLeft;
        float frameHeight = frameBottom - frameTop;

        if (getDrawable() != null) {

            Matrix matrix = getImageMatrix();
            float scaleFactor, scaleFactorWidth, scaleFactorHeight;

            scaleFactorWidth = (float) frameWidth / (float) getDrawable().getIntrinsicWidth();
            scaleFactorHeight = (float) frameHeight / (float) getDrawable().getIntrinsicHeight();

            if (scaleFactorHeight > scaleFactorWidth) {
                scaleFactor = scaleFactorHeight;
            } else {
                scaleFactor = scaleFactorWidth;
            }

            matrix.setScale(scaleFactor, scaleFactor, 0, 0);
            setImageMatrix(matrix);
        }

        return super.setFrame(frameLeft, frameTop, frameRight, frameBottom);
    }

}

https://stackoverflow.com/a/14815588/2075875

যদি কেউ কাস্টম অঙ্কনযোগ্য লিখেন যা এর মতো চিত্রটিকে স্কেল করে IM তারপরে এটি ব্যাকগ্রাউন্ড প্যারামিটার হিসাবে ব্যবহার করা যেতে পারে।


রিফ্লগ এটি ব্যবহারের আগে অঙ্কনযোগ্য প্রেস্কেল করার পরামর্শ দেয়। এটি কীভাবে করবেন তা এখানে নির্দেশনা দেওয়া হয়েছে: জাভা (অ্যান্ড্রয়েড): বিটম্যাপ ছাড়াই কীভাবে একটি অঙ্কনযোগ্য স্কেল করা যায়? যদিও এর অসুবিধা রয়েছে, তবে ছবিটি আপলোডকৃত অঙ্কনযোগ্য / বিটম্যাপটি আরও বেশি র‌্যাম ব্যবহার করবে, যখন চিত্রভিউ দ্বারা ব্যবহৃত ফ্লাই স্কেলিংয়ের জন্য আরও মেমরির প্রয়োজন হবে না। সুবিধা কম প্রসেসরের লোড হতে পারে।


সুন্দর! আমি ঠিক ঠিক পরে যা করেছি: ব্যাকগ্রাউন্ড চিত্রটি আনুপাতিকভাবে প্রস্থ বৃদ্ধি করে এবং চিত্রের নীচে থেকে ক্রপ করে পুরো স্ক্রীনটি পূরণ করবে।
সিএম্যাশ 16

4

নীচের কোডটি ইমেজভিউয়ের একই আকারের সাথে বিটম্যাপটি পুরোপুরি তৈরি করে। বিটম্যাপ চিত্রের উচ্চতা এবং প্রস্থ পান এবং তারপরে চিত্র প্রদর্শনের পরামিতিগুলির সাহায্যে নতুন উচ্চতা এবং প্রস্থ গণনা করুন। এটি আপনাকে সেরা দিক অনুপাত সহ প্রয়োজনীয় চিত্র দেয়।

int bwidth=bitMap1.getWidth();
int bheight=bitMap1.getHeight();
int swidth=imageView_location.getWidth();
int sheight=imageView_location.getHeight();
new_width=swidth;
new_height = (int) Math.floor((double) bheight *( (double) new_width / (double) bwidth));
Bitmap newbitMap = Bitmap.createScaledBitmap(bitMap1,new_width,new_height, true);
imageView_location.setImageBitmap(newbitMap)

2

ডুয়েবো প্রস্তাবিত কি কাজ করে। তবে আমার বিনীত মতে এটি অপ্রয়োজনীয়। একটি পটভূমি অঙ্কনযোগ্য স্কেল নিজেই ভাল by নিম্নলিখিত উদাহরণের মতো দৃশ্যের নির্দিষ্ট প্রস্থ এবং উচ্চতা থাকতে হবে:

 < RelativeLayout 
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@android:color/black">

    <LinearLayout
        android:layout_width="500dip"
        android:layout_height="450dip"
        android:layout_centerInParent="true"
        android:background="@drawable/my_drawable"
        android:orientation="vertical"
        android:padding="30dip"
        >
        ...
     </LinearLayout>
 < / RelativeLayout>

2
আমার বোধগম্যতা হল একটি পটভূমি কোনও দৃশ্য পূরণ করার জন্য প্রসারিত হবে, তবে সঙ্কুচিত হবে না।
এডওয়ার্ড ফাল

1

চেষ্টা করার একটি বিকল্প হ'ল চিত্রটি ছবিতে রাখা drawable-nodpi ফোল্ডারে রাখুন এবং বিন্যাসের পটভূমি অঙ্কনযোগ্য সংস্থান আইডিতে সেট করুন।

এটি অবশ্যই স্কেলিংয়ের সাথে কাজ করে, যদিও আমি স্কেলিংয়ের সাথে পরীক্ষা করিনি।


0

Kotlin:

আপনার যদি ভিউতে বিটম্যাপ আঁকার দরকার হয় তবে এফআইটি-তে স্কেল করা হয়েছে।

আপনি বিএম উচ্চতার ধারকের সমান উচ্চতা নির্ধারণ এবং প্রস্থ সামঞ্জস্য করার জন্য যথাযথ গণনা করতে পারেন, ক্ষেত্রে বিএম প্রস্থের উচ্চতা অনুপাতের ধারক প্রস্থের চেয়ে উচ্চতার অনুপাতের তুলনায় কম বা বিপরীত দৃশ্যে বিপরীত হওয়া।

ছবি:

উদাহরণ চিত্র 1

উদাহরণ চিত্র 2

// binding.fragPhotoEditDrawCont is the RelativeLayout where is your view
// bm is the Bitmap
val ch = binding.fragPhotoEditDrawCont.height
val cw = binding.fragPhotoEditDrawCont.width
val bh = bm.height
val bw = bm.width
val rc = cw.toFloat() / ch.toFloat()
val rb = bw.toFloat() / bh.toFloat()

if (rb < rc) {
    // Bitmap Width to Height ratio is less than Container ratio
    // Means, bitmap should pin top and bottom, and have some space on sides.
    //              _____          ___
    // container = |_____|   bm = |___| 
    val bmHeight = ch - 4 //4 for container border
    val bmWidth = rb * bmHeight //new width is bm_ratio * bm_height
    binding.fragPhotoEditDraw.layoutParams = RelativeLayout.LayoutParams(bmWidth.toInt(), bmHeight)
}
else {
    val bmWidth = cw - 4 //4 for container border
    val bmHeight = 1f/rb * cw
    binding.fragPhotoEditDraw.layoutParams = RelativeLayout.LayoutParams(bmWidth, bmHeight.toInt())
}

-4

আপনি এটি ব্যাকগ্রাউন্ড হিসাবে ব্যবহারের আগে সেই স্কেল প্রাক-স্কেল করতে হবে


এটি কি সত্যই একমাত্র বিকল্প? ইমেজভিউয়ের জন্য এমন কোনও ধারক নেই যা প্রদর্শন আকার নির্দিষ্ট করতে পারে?
GrkEngineer

সারফেসভিউ
এজেড_২৩

3
আইওএসের মতো দিক ফিট, পার্সেন্ট ফিল, শীর্ষ বাম, শীর্ষ ইত্যাদি কিছুই নেই? এটি
স্তন্যপান

@ অ্যালেক্সেস যেমন বলেছেন, একটি অসত্য উত্তর।
শিক্ষার্থী

-5

আপনি নিম্নলিখিতগুলির মধ্যে একটি ব্যবহার করতে পারেন:

অ্যান্ড্রয়েড মাধ্যাকর্ষণ = "fill_horizontal | clip_vertical"

অথবা

অ্যান্ড্রয়েড মাধ্যাকর্ষণ = "fill_vertical | clip_horizontal"

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