চিত্রটি দেখার প্রস্থটি পূরণ করতে এবং দিক অনুপাতটি রাখতে চিত্র স্কেল করুন


198

আমি একটি আছে GridView। এর ডেটাটি GridViewএকটি সার্ভার থেকে অনুরোধ করা হয়।

আইটেমের বিন্যাসটি এখানে রয়েছে GridView:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/analysis_micon_bg"
    android:gravity="center_horizontal"
    android:orientation="vertical"
    android:paddingBottom="@dimen/half_activity_vertical_margin"
    android:paddingLeft="@dimen/half_activity_horizontal_margin"
    android:paddingRight="@dimen/half_activity_horizontal_margin"
    android:paddingTop="@dimen/half_activity_vertical_margin" >

    <ImageView
        android:id="@+id/ranking_prod_pic"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:contentDescription="@string/app_name"
        android:scaleType="centerCrop" />

    <TextView
        android:id="@+id/ranking_rank_num"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/ranking_prod_num"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/ranking_prod_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

আমি সার্ভার থেকে ডেটা অনুরোধ করছি, চিত্র url পেতে এবং এতে চিত্র লোড করুন Bitmap

public static Bitmap loadBitmapFromInputStream(InputStream is) {
    return BitmapFactory.decodeStream(is);
}

public static Bitmap loadBitmapFromHttpUrl(String url) {
    try {
        return loadBitmapFromInputStream((InputStream) (new URL(url).getContent()));
    } catch (Exception e) {
        Log.e(TAG, e.getMessage());
        return null;
    }
}

এবং getView(int position, View convertView, ViewGroup parent)অ্যাডাপ্টারে পদ্ধতির কোড রয়েছে

Bitmap bitmap = BitmapUtil.loadBitmapFromHttpUrl(product.getHttpUrl());
prodImg.setImageBitmap(bitmap);

ছবির আকার হয় 210*210। আমি আমার নেক্সাস 4 এ আমার অ্যাপ্লিকেশনটি চালাব The চিত্রটি ImageViewপ্রস্থ পূরণ করে , তবে ImageViewউচ্চতাটি স্কেল করে না। ImageViewপুরো চিত্রটি দেখায় না।

আমি কীভাবে এই সমস্যার সমাধান করব?

উত্তর:


544

কোনও কাস্টম ক্লাস বা লাইব্রেরি ব্যবহার না করে:

<ImageView
    android:id="@id/img"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:adjustViewBounds="true"
    android:scaleType="fitCenter" />

scaleType="fitCenter" (বাদ দিলে ডিফল্ট)

  • এটিকে পিতামাতারা যতটা প্রশস্ত করতে চান তত প্রশস্ত করবে এবং উপরে / নিচে-স্কেলকে প্রয়োজনীয় অনুপাতটি রাখবে।

scaleType="centerInside"

  • যদি অভ্যন্তরীণ প্রস্থটি srcপিতামাতার প্রস্থের চেয়ে ছোট হয়
    তবে চিত্রটি অনুভূমিকভাবে কেন্দ্র করবে
  • যদি অভ্যন্তরীণ প্রস্থটি srcপিতামাতার প্রস্থের চেয়ে বড়
    হয় তবে এটি পিতামাতার অনুমতি অনুসারে তত প্রশস্ত এবং ডাউন-স্কেল রাখার দিক অনুপাতকে বাড়িয়ে তুলবে।

আপনি কী ব্যবহার করেন android:srcবা ImageView.setImage*পদ্ধতি ব্যবহার করেন তা বিবেচ্য নয় এবং কীটি সম্ভবত adjustViewBounds


5
অ্যান্ড্রয়েড: লেআউট_হাইট = "র‌্যাপ_কন্টেন্ট" অ্যান্ড্রয়েড: অ্যাডজাস্টভিউবাউন্ডস = "সত্য" অ্যান্ড্রয়েড: স্কেলটাইপ = "ফিটসেন্টার" কৌশলটি করে
জেমস ট্যান

প্রস্থের fill_parentজন্য জেমসটান কেবল একটি ভাল অনুশীলন, একটি নির্দিষ্ট আকারের পাশাপাশি কাজ করে।
TWiStErRob

@TWiStErRob আমি বুঝতে পারি যে এটির অ্যান্ড্রয়েডের প্রয়োজন: অ্যাডজাস্টভিউবাউন্ডস = এটির সাথে "সত্য", অন্যথায় এটি উচ্চতার জন্য সেই অনুযায়ী ফিট করে না। এবং হ্যাঁ, পিতামাতার সাথে মানানসই প্রস্থটি সম্পূর্ণ সংস্করণ
জেমস টান

9
এপিআই 19+ তে কবিতার মতো কাজ করে তবে এপিআই 16 তে নয় (পরীক্ষিত)। অ্যালেক্স সেমেনিয়ুকের কাস্টম ভিউ এপিআই 16 এও কাজ করে।
আশকান সরলাক

1
@ এফ.মাইসির চাবুক 😅, হ্যাঁ, সমস্যাটি কোনটির জন্য গুরুত্বপূর্ণ নয়, তবে ভাল অনুশীলন ছড়িয়ে দেওয়ার জন্য, আমি সম্পূর্ণ একমত।
TWiStErRob

42

আমি আরনেফের উত্তর পছন্দ করি তবে তিনি একটি ছোট ভুল করেছিলেন (মন্তব্য দেখুন) যা আমি সংশোধন করার চেষ্টা করব:

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;

/**
 * ImageView that keeps aspect ratio when scaled
 */
public class ScaleImageView extends ImageView {

  public ScaleImageView(Context context) {
    super(context);
  }

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

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

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    try {
      Drawable drawable = getDrawable();
      if (drawable == null) {
        setMeasuredDimension(0, 0);
      } else {
        int measuredWidth = MeasureSpec.getSize(widthMeasureSpec);
        int measuredHeight = MeasureSpec.getSize(heightMeasureSpec);
        if (measuredHeight == 0 && measuredWidth == 0) { //Height and width set to wrap_content
          setMeasuredDimension(measuredWidth, measuredHeight);
        } else if (measuredHeight == 0) { //Height set to wrap_content
          int width = measuredWidth;
          int height = width *  drawable.getIntrinsicHeight() / drawable.getIntrinsicWidth();
          setMeasuredDimension(width, height);
        } else if (measuredWidth == 0){ //Width set to wrap_content
          int height = measuredHeight;
          int width = height * drawable.getIntrinsicWidth() / drawable.getIntrinsicHeight();
          setMeasuredDimension(width, height);
        } else { //Width and height are explicitly set (either to match_parent or to exact value)
          setMeasuredDimension(measuredWidth, measuredHeight);
        }
      }
    } catch (Exception e) {
      super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
  }

}

সুতরাং আপনার ImageViewসঠিকভাবে স্কেল করা হবে এবং যদি (উদাহরণস্বরূপ) ভিতরে রাখা হয় তবে কোনও মাত্রিক সমস্যা হবে নাScrollView


thx, আমি সমাধানটি পেয়েছি, ঠিক arnefm এর উত্তরের নীচে, আমি যুক্ত করা প্রথম মন্তব্য। এটি thereএকটি লিঙ্ক
জো

36

আমারও একবার একই সমস্যা হয়েছিল। আমি এটি একটি কাস্টম ইমেজভিউ তৈরি করে সমাধান করেছি।

public class CustomImageView extends ImageView

তারপরে চিত্রদর্শনটির onMeasure পদ্ধতিটি ওভাররাইড করুন। আমি বিশ্বাস করি এরকম কিছু করেছিলাম:

    @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    try {
        Drawable drawable = getDrawable();

        if (drawable == null) {
            setMeasuredDimension(0, 0);
        } else {
            float imageSideRatio = (float)drawable.getIntrinsicWidth() / (float)drawable.getIntrinsicHeight();
            float viewSideRatio = (float)MeasureSpec.getSize(widthMeasureSpec) / (float)MeasureSpec.getSize(heightMeasureSpec);
            if (imageSideRatio >= viewSideRatio) {
                // Image is wider than the display (ratio)
                int width = MeasureSpec.getSize(widthMeasureSpec);
                int height = (int)(width / imageSideRatio);
                setMeasuredDimension(width, height);
            } else {
                // Image is taller than the display (ratio)
                int height = MeasureSpec.getSize(heightMeasureSpec);
                int width = (int)(height * imageSideRatio);
                setMeasuredDimension(width, height);
            }
        }
    } catch (Exception e) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

এটি অনুপাতের অনুপাত বজায় রেখে স্ক্রিনে ফিট করার জন্য চিত্রটিকে প্রসারিত করবে।


1
দেখতে সেখানে । প্রথম উত্তর
জো

ঠিক আছে, এই উত্তরটি সঠিক নয়। আপনি যেখানে সেট করেছেন সেই পরিস্থিতি বিবেচনা করুন android:layout_height="wrap_content"। এই ক্ষেত্রে MeasureSpec.getSize(heightMeasureSpec)হবে 0এবং আপনার viewSideRatioফলাফল হবে Infinity(অবাক হওয়ার দরকার নেই, জাভা ফ্লোট এই জাতীয় মানগুলিকে অনুমতি দেয়।) এক্ষেত্রে আপনার heightএবং উভয়ই widthহবে 0
অ্যালেক্স Semeniuk

1
আমার পূরণের কাজটি করার জন্য আমার (ইমেজসাইডারটিও> = ভিউসাইডারটিও) থেকে (ইমেজসাইডারটিও <ভিউসাইডারটিও) অদলবদল করতে হবে .. অন্যথায় একটি ভাল উত্তর
মেরেক হাল্মো

23

ব্যবহার android:scaleType="centerCrop"


প্রশ্নটি যা চেয়েছিল ঠিক তাই নয়, আমার ঠিক কী প্রয়োজন ছিল!
নিকজম

আপনি কি জেমসনকে বিস্তারিত বলতে পারবেন? আপনি কি অ্যান্ড্রয়েড সংস্করণ বোঝাতে চান?
মিক

যদি আমি কেন্দ্র ক্রপ ব্যবহার করি তবে চিত্রটি উপরে এবং নীচে কিছুটা কাটা হবে।
শ্রীকান্ত করুণাঘাট

9

আমি উপরের মতো অনুরূপ কিছু করেছি এবং তারপরে আমার মাথাটি কয়েক ঘন্টার জন্য প্রাচীরের বিরুদ্ধে বেঁধে দিয়েছিলাম কারণ এটি একটি এর ভিতরে কাজ করে না RelativeLayout। আমি নিম্নলিখিত কোডটি দিয়ে শেষ করেছি:

package com.example;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;

public class ScaledImageView extends ImageView {
    public ScaledImageView(final Context context, final AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
        final Drawable d = getDrawable();

        if (d != null) {
            int width;
            int height;
            if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY) {
                height = MeasureSpec.getSize(heightMeasureSpec);
                width = (int) Math.ceil(height * (float) d.getIntrinsicWidth() / d.getIntrinsicHeight());
            } else {
                width = MeasureSpec.getSize(widthMeasureSpec);
                height = (int) Math.ceil(width * (float) d.getIntrinsicHeight() / d.getIntrinsicWidth());
            }
            setMeasuredDimension(width, height);
        } else {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }
}

এবং তারপরে RelativeLayoutপরিমিত মাত্রাটিকে অগ্রাহ্য করা থেকে বিরত রাখতে আমি এটি করেছি:

    <FrameLayout
        android:id="@+id/image_frame"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/something">

        <com.example.ScaledImageView
            android:id="@+id/image"
            android:layout_width="wrap_content"
            android:layout_height="150dp"/>
    </FrameLayout>

5

দিক অনুপাত রাখতে ইমেজভিউতে এই বৈশিষ্ট্যগুলি ব্যবহার করুন:

android:adjustViewBounds="true"
android:scaleType="fitXY"

9
ফিটএক্সওয়াই অনুপাতের অনুপাত রাখে না। এটি লেআউটের প্রস্থ এবং উচ্চতার সাথে সঠিকভাবে ফিট করার জন্য চিত্রটিকে প্রসারিত করে।
পরিত্যক্ত কার্ট

5

চিত্রটি ভিউ-তে ব্যাকগ্রাউন্ড হিসাবে চিত্রটি সেট করা থাকলে, এসসিআর (অ্যান্ড্রয়েড: এসসিআর) সেট করতে হবে তবে এটি প্রযোজ্য হবে না।

ধন্যবাদ।


5

প্রস্থের সাথে স্ক্রিনের প্রস্থের সমান এবং উচ্চতা আনুপাতিকভাবে অনুপাত অনুসারে সেট করার জন্য একটি চিত্র তৈরি করতে নিম্নলিখিতগুলি করুন।

Glide.with(context).load(url).asBitmap().into(new SimpleTarget<Bitmap>() {
                    @Override
                    public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {

                        // creating the image that maintain aspect ratio with width of image is set to screenwidth.
                        int width = imageView.getMeasuredWidth();
                        int diw = resource.getWidth();
                        if (diw > 0) {
                            int height = 0;
                            height = width * resource.getHeight() / diw;
                            resource = Bitmap.createScaledBitmap(resource, width, height, false);
                        }
                                              imageView.setImageBitmap(resource);
                    }
                });

আশাকরি এটা সাহায্য করবে.


এটি আমি খুঁজে পেয়েছি সেরা উত্তর, আমি 2 দিন সন্ধান করছি, ফাতেমা ধন্যবাদ
কার্তিক রামানাথন


4

আপনার কোনও জাভা কোডের দরকার নেই। আপনার কেবলমাত্র:

<ImageView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:adjustViewBounds="true"
    android:scaleType="centerCrop" />

প্রস্থ এবং উচ্চতার জন্য কীটি ম্যাচ প্যারেন্টে রয়েছে


কেন্দ্রক্রপ আসলে চিত্রের কিছু অংশ কেটে দেয়।
শ্রীকান্ত করুণাঘাট

2

এই সাধারণ লাইনটি দিয়ে চেষ্টা করে দেখুন ... কোনও নির্ভরতা অ্যান্ড্রয়েড যুক্ত করে চিত্র ভিউ ট্যাগে আপনার এক্সএমএল কোডটিতে এই লাইনটি যুক্ত করুন: স্কেলটাইপ = "ফিটএক্সএইচ"


ফিটএক্সওয়াই দিক অনুপাত বজায় রাখে না তাই চিত্রটি সম্ভবত প্রসারিত হবে
প্রজেক্টডেল্টা

2

অ্যান্ড্রয়েড ব্যবহার করুন: স্কেলটাইপ = "ফিট এক্সওয়াই" ইমেজ ভিউ এক্সএমএল


ফিটএক্সওয়াই দিক অনুপাত বজায় রাখে না তাই চিত্রটি সম্ভবত প্রসারিত হবে
প্রজেক্টডেল্টা

1

আপনি ম্যানুয়ালি চিত্রগুলি লোড করে যা করছেন তা করার চেষ্টা করতে পারেন তবে আমি খুব জোরালোভাবে ইউনিভার্সাল ইমেজ লোডারটি একবার দেখে নেওয়ার পরামর্শ দেব ।

আমি সম্প্রতি এটি আমার প্রকল্পে একীভূত করেছি এবং এর চমত্কার বলতে হবে। আপনার জন্য বিষয়গুলি অ্যাসিক্রোনাস, আকার পরিবর্তন, এবং ক্যাশে ইমেজগুলি তৈরি করার বিষয়ে কি সমস্ত উদ্বেগজনক কাজ করে? এটি সংহত করা এবং সেট আপ করা সত্যই সহজ। 5 মিনিটের মধ্যে আপনি সম্ভবত এটি যা করতে চান তা পেতে পারেন।

উদাহরণ কোড:

//ImageLoader config
DisplayImageOptions displayimageOptions = new DisplayImageOptions.Builder().showStubImage(R.drawable.downloadplaceholder).cacheInMemory().cacheOnDisc().showImageOnFail(R.drawable.loading).build();

    ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext()).
            defaultDisplayImageOptions(displayimageOptions).memoryCache(new WeakMemoryCache()).discCache(new UnlimitedDiscCache(cacheDir)).build();

    if (ImageLoader.getInstance().isInited()) {
        ImageLoader.getInstance().destroy();
    }
    ImageLoader.getInstance().init(config);

    imageLoadingListener = new ImageLoadingListener() {
        @Override
        public void onLoadingStarted(String s, View view) {

        }

        @Override
        public void onLoadingFailed(String s, View view, FailReason failReason) {
            ImageView imageView = (ImageView) view;
            imageView.setImageResource(R.drawable.android);
            Log.i("Failed to Load " + s, failReason.toString());
        }

        @Override
        public void onLoadingComplete(String s, View view, Bitmap bitmap) {

        }

        @Override
        public void onLoadingCancelled(String s, View view) {

        }
    };

//Imageloader usage
ImageView imageView = new ImageView(getApplicationContext());
    if (orientation == 1) {
        imageView.setLayoutParams(new LinearLayout.LayoutParams(width / 6, width / 6));
    } else {
        imageView.setLayoutParams(new LinearLayout.LayoutParams(height / 6, height / 6));
    }
    imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
    imageLoader.displayImage(SERVER_HOSTNAME + "demos" + demo.getPathRoot() + demo.getRootName() + ".png", imageView, imageLoadingListener);

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

- আমার আরও যোগ করা উচিত যে এই বর্তমান কনফিগারেশনটি চিত্রের অনুপাতটি রাখে, সুতরাং এটি আপনার মূল প্রশ্নের ক্ষেত্রে প্রযোজ্য


0

কেবল ইউনিভার্সালআইমেজলডার এবং সেট ব্যবহার করুন

DisplayImageOptions.Builder()
    .imageScaleType(ImageScaleType.EXACTLY_STRETCHED)
    .build();

এবং ইমেজভিউতে কোনও স্কেল সেটিংস নেই


0

আমি একটি অনুরূপ সমস্যা ছিল, আমি দেখেছি এই জন্য কারণ কারণ আপনার গণনা করতে প্রয়োজন dp। অ্যান্ড্রয়েড স্টুডিও গণক হয় ImageViewযখন আপনার কাছ থেকে এটি লোড drawable, কিন্তু আপনি অন্য কোনো পদ্ধতি ব্যবহার করছেন যখন, থেকে ভালো লেগেছে লোড হচ্ছে বিটম্যাপdp স্বয়ংক্রিয়ভাবে জন্য দায়ী করা হয় না,

এখানে আমার এক্সএমএল

<ImageView
  android:id="@+id/imageViewer"
  android:layout_width="match_parent"
  android:layout_height="match_parent"//dp is not automaticly updated, when loading from a other source
  android:scaleType="fitCenter"
  tools:srcCompat="@drawable/a8" />

আমি কোটলিন ব্যবহার করছি, এবং একটি সম্পদ ফাইল থেকে অঙ্কনযোগ্য লোড করছি, আমি এখানে এটি কীভাবে গণনা করব তা এখানে

val d = Drawable.createFromStream(assets.open("imageData/${imageName}.png"), null)
bitHeight = d.minimumHeight//get the image height
imageViewer.layoutParams.height = (bitHeight * resources.displayMetrics.density).toInt()//set the height
imageViewer.setImageDrawable(d)//set the image from the drawable
imageViewer.requestLayout()//here I apply it to the layout

-1

পিকাসো ব্যবহার করুন যা ব্যবহার করা সহজ ..

আপনার অ্যাডাপ্টারে ..

@Override
public void getView(int position, View convertView, ViewGroup parent) {

 ImageView view = (ImageView) convertView.findViewById(R.id.ranking_prod_pic);

 Picasso.with(context).load(url).into(view); //url is image url

 //you can resize image if you want

 /* Picasso.with(context) .load(url) .resize(50, 50) .centerCrop() .into(view) */

}

http://square.github.io/picasso/ এখানে চিত্র বর্ণনা লিখুন

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