Масштабирование многослойных изображений, масштабированных на Android

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

Конечный результат. У меня есть базовое изображение с тремя слоями (прозрачные png) сверху. отображаемые слои зависят от пользователя. Каждый слой добавляет больше информации к базовому изображению. В моей ситуации базовым изображением является изображение звезд. Когда пользователь добавляет дополнительные слои, он может видеть границы созвездий, названия звезд и сетку. Пользователь также должен иметь возможность увеличивать область для получения более четкого изображения участка неба.

Первая проблема Размер изображения слишком велик (1324 × 1872), что вызывает ошибку OutOfMemory.

Решено путем масштабирования изображения с помощью

    /**
    * This method scales an image in the assets directory and returns a 
    * BitmapDrawable object that can be passed to an images setImageBitmap or a
    * views setBackgroundDrawable by passing this method into the constructor
    * of BitmapDrawable.
    * eg ViewGroup.setBackgroundDrawable(
    * new BitmapDrawable(getScaledBitMap(this, imagePath, 2)));
    * 
    * @param context
    * @param imgFullPath
    * @param imageSize
    * @return
    * @throws IOException
    */
    public static Bitmap getScaledBitMap(Context context, String imgFullPath,
        int imageSize)  throws IOException
    {
        InputStream instream;
        instream = context.getAssets().open(imgFullPath);

        BitmapFactory.Options options=new BitmapFactory.Options();
        options.inSampleSize = imageSize;
        Bitmap bitmap=BitmapFactory.decodeStream(instream, null, options);

        return bitmap;
    }

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

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

Решил это, установив фон FrameLayout на базовое изображение и оставив только 3 слоя в качестве дочерних для этого макета.

Третий вопрос Увеличение изображения. Я нашел, что может быть решением здесь Как я могу получить функциональность масштабирования для изображений?, но еще не проверял, так как эмулятор не поддерживает мультитач, и моему устройству это не понравилось, когда я взял его на плавание. В настоящее время у меня нет других устройств для тестирования.

Каков наилучший способ загрузить все 4 изображения (базовый + 3 слоя) без получения ошибки outOfMemoryError и иметь возможность масштабировать изображения.

Я создал проект с необходимым кодом здесь


person Stimsoni    schedule 11.01.2012    source источник


Ответы (1)


Я нашел несколько решений. Проблема первая: после завершения кода и использования TouchImageView найдено здесь. Я больше не получаю ошибки нехватки памяти. Я могу загрузить все слои без проблем.

Вторая и третья проблемы также были решены с помощью TouchImageView. Хотя я доволен этим, я бы хотел, чтобы в классе было больше комментариев, поскольку я потратил много времени, пытаясь понять, как это работает и почему, но в конце концов потерпел неудачу.

Последняя большая проблема, с которой я столкнулся, заключалась в том, что при масштабировании щипком масштабировался только верхний слой (как и ожидалось). Исправление этого состояло в том, чтобы немного изменить класс TouchImageview и добавить функциональность для прослушивателя измененной матрицы. Теперь, когда матрица изменяется, матрица возвращается слушателю, который затем обновляет матрицу во всех слоях, включая базовое изображение. Теперь все изображения масштабируются одновременно, сохраняя метки, указывающие на одно и то же место на базовом изображении независимо от масштаба.

Это очень простой интерфейс, используемый для уведомления слушателей об изменении матрицы.

public interface IOnMatixChangedListener
{
        public void onMatrixChanged(Matrix matrix);
}
person Stimsoni    schedule 25.01.2012