Android: качество изображений изменено во время выполнения

Я хочу показывать изображения с помощью метода drawBitmap(). Но прежде чем я хочу изменить его размер в соответствии с размерами экрана. У меня проблема с качеством изображения результата. Вы можете увидеть скриншоты и тестовый код ниже. Как я могу изменить размер изображений во время выполнения с хорошим качеством?

Спасибо за решения.

Исходное изображение: http://dl.dropbox.com/u/709109/gradient.png

Скриншот результата на устройстве: замещающий текст http://dl.dropbox.com/u/709109/device.png

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.os.Bundle;
import android.view.View;
import android.widget.LinearLayout;

import java.io.IOException;
import java.io.InputStream;

public class MyActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        LinearLayout container = (LinearLayout) findViewById(R.id.container);
        container.addView(new View(this) {
            @Override
            protected void onDraw(Canvas canvas) {
                Bitmap unscaledBitmap;
                try {
                    InputStream in = getAssets().open("images/gradient.png");
                    unscaledBitmap = BitmapFactory.decodeStream(in);
                    in.close();
                    canvas.drawBitmap(unscaledBitmap, null, new Rect(0, 0, 320, 480), null);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

person shinydev    schedule 11.01.2010    source источник


Ответы (6)


Пожалуйста, обратитесь к ответу Ромена ниже.

Я хотел бы удалить этот ответ, но не могу, так как он помечен как принятый.


Обратите внимание, что Android [когда этот ответ был первоначально написан, без явного запроса 32-битного цвета] будет использовать только 16-битный цвет, поэтому могут быть случаи, когда вы получаете нежелательные артефакты.

Вы также можете попробовать использовать параметры сглаживания, чтобы указать Android автоматически применять сглаживание, что, хотя и не идеально, может помочь немного улучшить внешний вид.

person Christopher Orr    schedule 11.01.2010
comment
Спасибо, это полезный ответ! Но у меня нет репутации, чтобы голосовать за это. - person shinydev; 11.01.2010
comment
Теперь я использую плагин 565 dither для фотошопа, чтобы подготовить свою графику. Поскольку сглаживание — это дорогостоящая операция, и она не работает с методами decodeStream и drawBitmap. - person shinydev; 11.01.2010
comment
Андроид прекрасно справляется с 32 битами. Просто убедитесь, что и ваше растровое изображение, и ваше окно используют формат ARGB8888. - person Romain Guy; 22.01.2012
comment
@RomainGuy Всегда ли так было? Просто интересно, было ли это правдой два года назад, когда я писал это .. :) В любом случае, я удалю свой ответ в пользу вашего, за который я, по-видимому, также проголосовал два года назад! - person Christopher Orr; 22.01.2012
comment
Это было верно 2 года назад, это просто должно было быть запрошено приложением. 32 бита теперь по умолчанию. - person Romain Guy; 23.01.2012
comment
@Roces не волнуйся, я сделал это для тебя - person Akshat Agarwal; 07.12.2013

Вместо того, чтобы изменять размер во время рисования (что будет очень дорого), попробуйте изменить размер внеэкранного растрового изображения и убедитесь, что растровое изображение является 32-битным (ARGB888).

person Romain Guy    schedule 11.01.2010
comment
Как я понял, Android применяет хороший алгоритм уменьшения масштаба (не ближайший сосед) только при использовании BitmapFactory.Options::inSampleSize-›BitmapFactory.decodeResource(), но это позволяет для уменьшения масштаба только в ровно целое число раз меньше, чем оригинал. Есть ли способ уменьшить масштаб в Android до точного разрешения, которое мне нужно, используя что-то лучшее, чем алгоритм ближайшего соседа (который используется каждый раз, когда я вызываю createScaledBitmap(), createBitmap+matrix и т. д.)? - person goRGon; 21.04.2014

Ознакомьтесь с http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html (для использования с unscaledBitmap = BitmapFactory.decodeStream(in);

Вы можете добавить настройки качества к изображению. Я предполагаю, что качество ухудшается, поскольку вы не передаете никаких настроек для обработки изображения.

person Steve    schedule 11.01.2010
comment
какие настройки качества в BitmapFactory.Options? Я не вижу ни одного, и слово «качество» ни разу не встречается в документации. - person William Denniss; 22.11.2010
comment
Там есть developer.android.com/reference/android/graphics/, но в документах говорится, что это относится только к декодированию JPEG, а ваш файл - PNG. - person typo.pl; 13.02.2011

Реализации метода createScaledBitmap(..) на более старых платформах (уровень API ‹ 12) вызывают проблемы, когда вы пытаетесь масштабировать растровое изображение ARGB_8888, которое не имеет фактического значения альфа-канала (т. е. каждый пиксель имеет альфа-канал = 255), поскольку установлен флаг hasAlpha. к ложному. В этом случае масштабированное растровое изображение автоматически преобразуется в формат RGB_565.

Поэтому начиная с уровня API 12 существует метод (в классе Bitmap)

setHasAlpha(boolean value);

Что помогает предотвратить преобразование при использовании createScaledBitmap(..).

Есть способ использовать тот же метод на уровне API > 3. Он существует уже очень давно, просто скрыт. Все необходимые шаги, включая исходный код, описаны здесь:

https://stackoverflow.com/a/12202069/1082933

Надеюсь это поможет.

person Ivo    schedule 30.08.2012

У меня была аналогичная проблема, и вот что я в итоге сделал: Проблемы с качеством при изменении размера изображения во время выполнения

person cottonBallPaws    schedule 22.11.2010

Кроме того, если ваша функция изменения размера не учитывает соотношение сторон изображения, это влияет на качество. Вы можете найти алгоритм изменения размера в Интернете, например, проверьте это

person Samuh    schedule 11.01.2010
comment
Нет, оба изображения имеют одинаковое соотношение. исходное изображение: 600x900, соотношение 1,5 новое изображение: 320x480, соотношение 1,5 - person shinydev; 11.01.2010
comment
По указанной вами ссылке алгоритма изменения размера не нашел. Просто обсуждение правильного расчета значения масштаба... - person goRGon; 21.04.2014