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

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

Окончательный результат У меня есть базовое изображение, которое имеет 3 слоя (прозрачные 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 при загрузке 3 слоев. Я также думаю, что масштабирование изображения будет проблемой при масштабировании, так как качество было снижено.

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

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

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

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

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

1 ответ

Решение

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

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

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

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

public interface IOnMatixChangedListener
{
        public void onMatrixChanged(Matrix matrix);
}
Другие вопросы по тегам