Мащабирани изображения със залп

Опитвам се да разтегля изображения, които зареждам със залпове. XML не е много полезен, въпреки че може да ги свие, не помага да ги увеличите. Проучването ми по темата ме доведе до извода, че това може да се постигне само програмно.

Каква е идеята ми?

За да разширите библиотеката за залпове и да замените един от методите, преоразмерете растерното изображение веднага след изтегляне и преди да го покажете.

Използвах този код за преоразмеряване на изображения, които вече бяха на телефона, но това не ми помага много с произволни изображения от интернет.

        Point outSize=new Point();
        float  destWidth=1;
        float  destHeight=1;

        @SuppressWarnings("deprecation")
        @TargetApi(13)
        private Bitmap scaleBitmap(int mFile){
            Display display = getActivity().getWindowManager().getDefaultDisplay();
            if (android.os.Build.VERSION.SDK_INT >= 13){
                display.getSize(outSize);
                destWidth = outSize.x;
                destHeight = outSize.y;
            }else{
                destWidth=display.getWidth();
                destWidth=display.getHeight();
            }

            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            Bitmap orig = BitmapFactory.decodeResource(getResources(), mFile);
            float srcWidth = orig.getWidth();
            float srcHeight = orig.getHeight();
            float inSampleSize = 1;
            if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
                inSampleSize=(destHeight/2)/srcHeight;
            }else{
            inSampleSize=(destHeight/4)/srcHeight;}
            options = new BitmapFactory.Options();
            Bitmap resized=Bitmap.createScaledBitmap(orig, (int)Math.round(orig.getWidth()*inSampleSize), (int)Math.round(orig.getHeight()*inSampleSize), true);
            destWidth=1;
            destHeight=1;
            return resized;
        }

По принцип искам да присвоя на orig изображението, което е изтеглено, след това да го преоразмеря и след това да го покажа. Въпросът ми е: Какъв клас да продължа? Погледнах там, но тъй като нямам опит, не можах да разбера какво точно да търся. ImageLoader ли е? И по-конкретно: трябва ли да отменя метода getBitmap() и да добавя редактирана версия на кода за мащабиране?

Отказ от отговорност: Аз съм много неопитен и бих приел и други идеи.


person user3542472    schedule 11.11.2014    source източник
comment
Използвате ли NetworkImageView? Трябва да направи мащабирането вместо вас.   -  person zgc7009    schedule 12.11.2014
comment
да Опитах да използвам настройката linearlayout androdi_weight, но картината остава същата. Изгледът обаче става по-голям (което означава, че фоновото изображение се разтяга, за да пасне). Както казах, картината става по-малка, ако намаля теглото, но след достигане на оригиналния размер спира. Това е мястото, където искам да добавя преоразмеряването.   -  person user3542472    schedule 12.11.2014
comment
Трябва да промените scaleType на вашия NetworkImageView. Опитайте android:scaleType=fitCenter   -  person zgc7009    schedule 12.11.2014
comment
Опитах всичките 8 опции на scaleType и нито една не прави това, от което се нуждая. Имам нужда картината да съвпада с_parent по ширина и да заема толкова място, колкото е необходимо по височина (wrap_content). Но нито една от опциите в scaleType не прави това. Те или не го съвпадат вътре в родителя, или изкривяват или изрязват изображението. За layout_width и height използвам съответно match/wrap.   -  person user3542472    schedule 12.11.2014
comment
Пасва добре на X, но го изкривява на Y. Не запазва същото съотношение.   -  person user3542472    schedule 12.11.2014
comment
Мисля, че може да съм объркан и да не помогна много. Ако имате NetworkImageView с width:wrap_content и height:match_parent със scaleType:centerInside, трябва да направите това, което искате. ще обвие съдържанието на ширината, ще мащабира равномерно изображението и ще се увери, че височината или ширината пасват напълно. Ако искате да го мащабирате, за да сте сигурни, че ширината пасва, какво се случва, ако вашето изображение е по-високо, отколкото е широко? Ще се разтегне извън гледката или ще се изкриви. Това ли искаш?   -  person zgc7009    schedule 12.11.2014
comment
Имам нужда от width:match_parent и height:wrap_content. Когато използвам centerInside, той не прави нищо, само изображението с оригинална резолюция. Ако използвам centerCrop, той мащабира X и Y, но изрязва части от изображението върху Y. Нямам представа защо е така, тъй като цялото оформление се основава на wrap_content по височина.   -  person user3542472    schedule 12.11.2014


Отговори (2)


Реших го преди няколко дни. Ето как обикновеният ImageView обработва преоразмеряването на изображенията: Ако използвате Match_parent като ширина и wrap_content като височина (тествах и с двете като match_parent и резултатите бяха същите), той НЯМА да мащабира изображението, АКО височината на вашата картина е по-ниска отколкото ширината (което е доста типично). Това означава, че изгледът на изображението се мащабира въз основа на по-малката страна. Това означаваше, че има 2 решения:

  • Направете това, което исках да направя първоначално, което включва писане на нов клас, който разширява imageview/networkimageview и след това програмно добавяне на кода, който изброих, за уголемяване на картината.
  • Или просто задайте желаната височина на изгледа програмно и след това imageview просто ще мащабира изображението, за да пасне на височината на новия изглед. Тази опция обезсилва wrap_content за Width и просто поставя толкова, колкото ви е необходимо.

Ето кода, който използвах:

 Display display = getActivity().getWindowManager().getDefaultDisplay();
 Point outSize=new Point();
 int destWidth;
 if (android.os.Build.VERSION.SDK_INT >= 13){
    display.getSize(outSize);
    destWidth = outSize.x;
 }else{
    destWidth=display.getWidth();
 }
 img.setLayoutParams(new RelativeLayout.LayoutParams( LayoutParams.MATCH_PARENT,destWidth*5625/10000));

В моя случай трябваше да побера изображение с размери 640x360, така че използвах съотношение 0,5625. Този метод ще работи, ако не знаете параметрите на картината, НО трябва да получите параметрите предварително и да ги поставите на място, така че предполагам, че може да е по-полезно да използвате първата стратегия, но тъй като реших проблема си, не го правя има пример за първия метод.

person user3542472    schedule 26.11.2014

Мисля, че проблемът, който виждате, е причинен от поведението по подразбиране на начина, по който работи основният код за NetworkImageView.

Разгледайте кода за ImageRequest, който се използва от NetworkImageView. Там има функция, наречена getResizedDimension, която казва нещо като „Мащабира едната страна на правоъгълник, за да пасне на съотношението на страните“. Това може да е причинило проблема ви, тъй като изображенията, които изтегляте, може да нямат идеалното съотношение, изчислено всеки път за конкретно устройство.

Показвате ли едно изображение или изображения в решетка? Ако това е само едно изображение, може да има заобикаляне. Не съм виждал пълния ви код, къде сте задали изображението или URL адреса на изображението, така че ще приема потока тук:

1.) Използвайте обикновения ImageView.

2.) Използвайте обикновената заявка Volley, сочеща към URL адреса на изображението

3.) Когато получите отговора (parseNetworkResponse), декодирайте (масива от байтове) сами, като използвате метода, който споменахте по-горе, който работи за вас. Някои съвети могат да бъдат намерени и тук как да направите това: http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

4.) След декодиране, задайте програмно растерното изображение на ImageView с вашия декодиран резултат

Ако това е нещо от тип мрежа, тогава може би трябва да направите своя собствена версия на NetworkImageView и неговите базови класове за поддръжка (подклас).

Предложение:

Разгледайте и Picasso, АКО имате свободата да избирате библиотеката. Изглежда много лесно за използване за вашите заявени нужди.

person alpinescrambler    schedule 11.11.2014