বিটম্যাপফ্যাক্টরি.ডেকোড স্ট্রিম অপশন সেট করা হলে ফিরতে শূন্য


90

আমি সমস্যা আছে BitmapFactory.decodeStream(inputStream)। বিকল্পগুলি ছাড়াই এটি ব্যবহার করার সময়, এটি একটি চিত্র ফিরে আসবে। আমি যখন বিকল্পগুলির সাথে এটি ব্যবহার করি তখন .decodeStream(inputStream, null, options)এটি কখনই বিটম্যাপগুলি দেয় না।

আমি যা করার চেষ্টা করছি তা হ'ল মেমরিটি সংরক্ষণ করতে আসলে এটি লোড করার আগে বিটম্যাপটি ডাউনসাম্পল করা। আমি কিছু ভাল গাইড পড়েছি, কিন্তু কেউই ব্যবহার করছে না .decodeStream

জাস্ট জরিমানা কাজ

URL url = new URL(sUrl);
HttpURLConnection connection  = (HttpURLConnection) url.openConnection();

InputStream is = connection.getInputStream();
Bitmap img = BitmapFactory.decodeStream(is, null, options);

কাজ করবেন না

InputStream is = connection.getInputStream();
Bitmap img = BitmapFactory.decodeStream(is, null, options);

InputStream is = connection.getInputStream();

Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;

BitmapFactory.decodeStream(is, null, options);

Boolean scaleByHeight = Math.abs(options.outHeight - TARGET_HEIGHT) >= Math.abs(options.outWidth - TARGET_WIDTH);

if (options.outHeight * options.outWidth * 2 >= 200*100*2){
    // Load, scaling to smallest power of 2 that'll get it <= desired dimensions
    double sampleSize = scaleByHeight
    ? options.outHeight / TARGET_HEIGHT
    : options.outWidth / TARGET_WIDTH;
    options.inSampleSize =
        (int)Math.pow(2d, Math.floor(
        Math.log(sampleSize)/Math.log(2d)));
}

// Do the actual decoding
options.inJustDecodeBounds = false;
Bitmap img = BitmapFactory.decodeStream(is, null, options);

4
আপনার System.out.println ("নমুনা:" ...) বিবৃতি থেকে আউটপুট কী? বিকল্প ইঙ্গিত দিচ্ছে কি? নমুনা আকার একটি গ্রহণযোগ্য মান?
স্টিভ হ্যালি

হ্যাঁ, এটি প্রতিবার গ্রহণযোগ্য মান দেয়।
রবার্ট ফস

ডিবাগ হওয়ার কারণে বিবৃতিটি সরানো হয়েছে।
রবার্ট ফস

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

নতুন ব্যবহারকারীকে সম্প্রদায়ে একীভূত করতে সহায়তা করার জন্য ধন্যবাদ :)
রবার্ট ফস

উত্তর:


114

সমস্যাটি হ'ল একবার আপনি চিত্রের মেটাডেটা আনতে কোনও HTTPUrlConnication থেকে ইনপুট স্ট্রিম ব্যবহার করলে আপনি আবার একই ইনপুট স্ট্রিমটি রিওয়াইন্ড এবং ব্যবহার করতে পারবেন না।

সুতরাং আপনাকে চিত্রটির প্রকৃত নমুনার জন্য একটি নতুন ইনপুটস্ট্রিম তৈরি করতে হবে।

  Options options = new BitmapFactory.Options();
  options.inJustDecodeBounds = true;

  BitmapFactory.decodeStream(is, null, options);

  Boolean scaleByHeight = Math.abs(options.outHeight - TARGET_HEIGHT) >= Math.abs(options.outWidth - TARGET_WIDTH);

  if(options.outHeight * options.outWidth * 2 >= 200*200*2){
         // Load, scaling to smallest power of 2 that'll get it <= desired dimensions
        double sampleSize = scaleByHeight
              ? options.outHeight / TARGET_HEIGHT
              : options.outWidth / TARGET_WIDTH;
        options.inSampleSize = 
              (int)Math.pow(2d, Math.floor(
              Math.log(sampleSize)/Math.log(2d)));
     }

        // Do the actual decoding
        options.inJustDecodeBounds = false;

        is.close();
        is = getHTTPConnectionInputStream(sUrl);
        Bitmap img = BitmapFactory.decodeStream(is, null, options);
        is.close();

17
এর অর্থ কি চিত্রটি দুইবার ডাউনলোড করতে হবে? একবার সাইজ পেতে এবং একবার পিক্সেল ডেটা পেতে?
ব্যবহারকারী 123321

4
@ রবার্ট আপনার সম্ভবত এই নির্দিষ্ট আচরণটি ব্যাখ্যা করা উচিত যাতে অন্যান্য ব্যবহারকারীরা সে সম্পর্কে একটি পরিষ্কার ধারণা পেতে পারে
মুহাম্মদ বাবর

4
আমি ভাবছিলাম কেন এটি নিজেই একই ইনপুটস্ট্রিমে কাজ করবে না, সংক্ষিপ্ত ব্যাখ্যার জন্য ধন্যবাদ
kabuto178

4
আপনাকে এটিকে পুনরায় তৈরি করতে হবে না, কেবল পুনরায় পুনর্নির্মাণের উদ্দেশ্যটি সমাধান হবে। আমার উত্তর দেখুন
শশাঙ্ক তোমার

4
আমাকে বলতে হবে বিটম্যাপের ক্লাসটি অ্যান্ড্রয়েড চুষছে। এটি এত বিভ্রান্তিকর এবং ব্যবহারে হতাশ।
নিয়ন ওয়ার্জ

30

ইনফর্ম স্ট্রিম বাফারডিনপুটস্ট্রিমে মোড়ানো চেষ্টা করুন।

InputStream is = new BufferedInputStream(conn.getInputStream());
is.mark(is.available());
// Do the bound decoding
// inJustDecodeBounds =true
is.reset();  
// Do the actual decoding

4
এটা কি সবসময় আপনার জন্য কাজ করে? কোনও কারণে, আমি এই পদ্ধতিটি ব্যবহার করে খুব নির্দিষ্ট কিছু ক্ষেত্রে বাতিল হয়ে যাই। আমি এটি সম্পর্কে এখানে একটি পোস্ট লিখেছি: stackoverflow.com/questions/17774442/…
অ্যান্ড্রয়েড বিকাশকারী

4
এটি কাজ করেছিল তাই আমি এটিকে উজ্জীবিত করেছি তবে উপলব্ধ (উপলভ্য) ডকটি সতর্কবার্তা নিয়ে আসে যে এটি কেবলমাত্র স্ট্রিমটি খালি কিনা তা পরীক্ষা করার জন্য ব্যবহার করা উচিত এবং আকারটি গণনা করার জন্য নয় কারণ এটি বিশ্বাসযোগ্য নয়।
অভিষেক চৌহান

4
নিচে ভোট দেওয়া হয়েছে, তবে প্রশ্নে থাকা ইনপুটস্ট্রিম সংযোগটি একটি এইচটিটিপি সংযোগ এবং পুনরায় সেট করা () কাজ করবে না ....
জনি

3

আমি মনে করি সমস্যাটি "ক্যালকুলেট-স্কেল-ফ্যাক্টর" যুক্তির সাথে রয়েছে কারণ বাকী কোডটি আমার কাছে সঠিক দেখাচ্ছে (অবশ্যই ধরে নেওয়া যায় যে ইনপুটস্ট্রিমটি বাতিল নয়)।

আপনি যদি এই রুটিন থেকে সমস্ত আকারের গণনা যুক্তি যুক্ত করে কোনও পদ্ধতিতে (একে কলকুলেটস্কেলফ্যাক্টর () বা যাই হোক না কেন) কল করতে পারেন এবং প্রথমে স্বাধীনভাবে সেই পদ্ধতিটি পরীক্ষা করতে পারেন তবে ভাল better

কিছুটা এইরকম:

// Get the stream 
InputStream is = mUrl.openStream();

// get the Image bounds
BitmapFactory.Options options=new BitmapFactory.Options(); 
options.inJustDecodeBounds = true;

bitmap = BitmapFactory.decodeStream(is,null,options);

//get actual width x height of the image and calculate the scale factor
options.inSampleSize = getScaleFactor(options.outWidth,options.outHeight,
                view.getWidth(),view.getHeight());

options.inJustDecodeBounds = false;
bitmap=BitmapFactory.decodeStream(mUrl.openStream(),null,options);

এবং স্বতন্ত্রভাবে getScaleFactor (...) পরীক্ষা করুন।

এটি চেষ্টা করে পুরো কোডটি ঘিরে ফেলতে সহায়তা করবে {


ধন্যবাদ উত্তরের জন্য অনেক! আমি চূড়ান্ত কোন মান সেট করার চেষ্টা করেছি 'বিকল্পগুলি.ডম্যাম্পল সাইজ = 2' এর মতো। কিন্তু এটি একই সমস্যা ফলাফল। লগক্যাটটি 'স্কাইম্যাজডেকোডার :: ফ্যাক্টরি নাল' পড়েছে, আমি যে চিত্রটি ডিকোড করার চেষ্টা করেছি for কোনও চেষ্টা / ক্যাচ ব্লকের ভিতরে কোড চালানো আমার কোনও উপকারে আসবে না কারণ এটি কিছু ফেলেছে না, তাই না? তবে বিটম্যাপফ্যাক্টরি.ডেকোড স্ট্রিমটি যদি কোনও ইম্জি তৈরি করতে না পারে তবে তা বাতিল করে দেয়, যা আমি যখন স্যাম্পল সাইজ ব্যবহার করার চেষ্টা করি তখন তা ক্যান্ট করে না।
রবার্ট ফস

এটা অদ্ভুত. আপনি কি আপনার সংস্থানটিতে কিছু বিটম্যাপের বান্ডিলকে পুনরায় আকার দেওয়ার চেষ্টা করতে পারেন? রিসোর্স ফাইল খুলুন এবং এটিকে ডিকোড করার চেষ্টা করুন। যদি আপনি এটি করতে পারেন তবে দূরবর্তী স্ট্রিমের সাথে কিছু সমস্যা রয়েছে যা ডিকোডকে ব্যর্থ করে তুলছে।
সামুহ

বিটম্যাপফ্যাক্টরি.ডেকোডেরোসোর্স (এটি.জেটআরসোর্সস (), আরড্রাব্যাবল.আইকন, অপশন) == নাল) রি-স্যাম্পলিংয়ের সাথে দুর্দান্ত কাজ করে। বিকল্প বিটম্যাপফ্যাক্টরি.ডেকোডস্ট্রিম.ডাস্টকডস্টাউন্ডস = সত্য কাজ করে এবং বিকল্পগুলি ঠিকঠাক করে দেয়। কিন্তু নিম্নলিখিত বিটম্যাপফ্যাক্টরি.ডেকোড স্ট্রিম অপশন.জাস্টডেকোডবাউন্ডস = মিথ্যা প্রতিবার ব্যর্থ হয়।
রবার্ট ফস

আমি ভয় পাচ্ছি যে এটি আমার বাইরে নয় ... আমি এখানে সম্ভবত কী ভুল হতে পারে তা জানতে আগ্রহী কারণ আমি একই কোড ব্যবহার করছি এবং এটি আমার পক্ষে ঠিক কাজ করে।
সামুহ

4
ঠিক আছে. আমি সমাধান করেছি। বিষয়টি http- সংযোগের মধ্যে রয়েছে। আপনি যখন একবার এইচটিটিপিআরলকনেকশন দ্বারা সরবরাহ করা ইনপুট-স্ট্রিমটি পড়েছেন, আপনি এটি থেকে আর পড়তে পারবেন না, এবং দ্বিতীয় ডিকোডস্ট্রিম () করতে পুনরায় সংযোগ করতে হবে।
রবার্ট ফস

2

আপনি ইনপুট স্ট্রিমটিকে একটি বাইট অ্যারেতে রূপান্তর করতে পারেন এবং ডিকোডবাইটআরে () ব্যবহার করতে পারেন। উদাহরণ স্বরূপ,

public static Bitmap decodeSampledBitmapFromStream(InputStream inputStream, int reqWidth, int reqHeight) {
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    try {
        int n;
        byte[] buffer = new byte[1024];
        while ((n = inputStream.read(buffer)) > 0) {
            outputStream.write(buffer, 0, n);
        }
        return decodeSampledBitmapFromByteArray(outputStream.toByteArray(), reqWidth, reqHeight);
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return null;
}

public static Bitmap decodeSampledBitmapFromByteArray(byte[] data, int reqWidth, int reqHeight) {
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeByteArray(data, 0, data.length, options);
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeByteArray(data, 0, data.length, options);
}

private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int
        reqHeight) {
    int width = options.outWidth;
    int height = options.outHeight;
    int inSampleSize = 1;
    if (width > reqWidth || height > reqHeight) {
        int halfWidth = width / 2;
        int halfHeight = height / 2;
        while (halfWidth / inSampleSize >= reqWidth && halfHeight / inSampleSize >= reqHeight) {
            inSampleSize *= 2;
        }
    }
    return inSampleSize;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.