Слияние файлов png программно - PullRequest
0 голосов
/ 08 ноября 2019

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

Я создаю математическое приложение, дружественное к детям, и поэтому использую файлы .png для отображения соответствующих чисел. У меня есть числа 0-9 в формате png (необходимые для прозрачных свойств) в папке drawable, и тестирование работало, используя только цифры 0-9, но я хочу, чтобы область приложения пошла дальше - числа> 10 (возможно,> 100) - но чувствую, что размер приложения будет слишком большим, если я создаю png-файл для каждого числа и, следовательно, хочу программно объединить число png-файлов для отображения и затем удалить их (если единственный способ - создать новый файл для отображения).

Во-первых, я ввел файлы в массив растровых изображений -

    bitmapNumbers[0] = BitmapFactory.decodeResource(getResources(), R.drawable.zero);
    bitmapNumbers[1] = BitmapFactory.decodeResource(getResources(), R.drawable.one);
    bitmapNumbers[2] = BitmapFactory.decodeResource(getResources(), R.drawable.two);
    bitmapNumbers[3] = BitmapFactory.decodeResource(getResources(), R.drawable.three);
    bitmapNumbers[4] = BitmapFactory.decodeResource(getResources(), R.drawable.four);
    bitmapNumbers[5] = BitmapFactory.decodeResource(getResources(), R.drawable.five);
    bitmapNumbers[6] = BitmapFactory.decodeResource(getResources(), R.drawable.six);
    bitmapNumbers[7] = BitmapFactory.decodeResource(getResources(), R.drawable.seven);
    bitmapNumbers[8] = BitmapFactory.decodeResource(getResources(), R.drawable.eight);
    bitmapNumbers[9] = BitmapFactory.decodeResource(getResources(), R.drawable.nine);

, а когда загружается Activity, он вызывает метод для генерации суммы и ее отображения пользователю. потребовать пользовательский ввод, который вызывает другой метод, чтобы проверить ответ. Ниже приведен метод generateSum -

public void generateSum () {

    String stringFirst;
    String stringSecond;

    Bitmap[] buildFirst;
    Bitmap[] buildSecond;

    String newFile = "";

    Random rand = new Random();

    // generate first random number

    firstNumber = rand.nextInt(highestNumber + 1);
    stringFirst = String.valueOf(firstNumber);
    int[] splitFirst = new int[stringFirst.length()];

    for (int i = 0; i < stringFirst.length(); i++) {

        // split number down to individual 'single-digit' elements

        splitFirst[i] = Integer.parseInt(stringFirst.substring(i, i + 1));

    }

    // generate second random number

    secondNumber = rand.nextInt(highestNumber + 1);
    stringSecond = String.valueOf(secondNumber);
    int[] splitSecond = new int[stringSecond.length()];

    for (int i = 0; i < stringSecond.length(); i++) {

        // split number down to individual 'single-number' elements

        splitSecond[i] = Integer.parseInt(stringSecond.substring(i, i + 1));

    }

    // calculate sum answer depending on mode selected in setup

    switch (sPrefs.getString("sumMethod", null)) {
        case ("Addition"):
            answer = firstNumber + secondNumber;
            break;
        case ("Subtraction"):
            if (secondNumber > firstNumber) {
                while (secondNumber > firstNumber) {

                    firstNumber = rand.nextInt(highestNumber + 1);
                    secondNumber = rand.nextInt(highestNumber + 1);

                }
            }
            answer = firstNumber - secondNumber;
            break;
        case ("Multiplication"):
            answer = firstNumber * secondNumber;
            break;
        default:
            return;
    }

    // build Bitmap array based on first number generated and split

    buildFirst = new Bitmap[splitFirst.length];

    for (int i = 0; i < splitFirst.length; i++) {
        for (int j = 0; j <= 9; j++) {
            if (j == splitFirst[i]) {

                // built from Bitmap array containing .png drawable resources

                buildFirst[i] = bitmapNumbers[j];

            }
        }
    }

    // code to generate new merged .png file based on built arrays and .png files

    Bitmap builtFirst = Bitmap.createBitmap(buildFirst[0].getWidth(), buildFirst[0].getHeight(), buildFirst[0].getConfig());
    Canvas canvas = new Canvas(builtFirst);
    newFile = buildFirst[0].toString();

    if (buildFirst.length > 1) {

        for (int i = 1; i < buildFirst.length; i++) {

            canvas.drawBitmap(buildFirst[i], 0, 0, null);
            canvas.drawBitmap(builtFirst, new Matrix(), null);
            newFile = newFile + buildFirst[i].toString();

        }
    }

    try {

        FileOutputStream out = new FileOutputStream("android.resource://com.app.numberup/drawable/" + newFile);
        builtFirst.compress(Bitmap.CompressFormat.PNG, 100, out);

        imageViewFirstNumber.setImageBitmap(builtFirst);

    } catch (Exception e) {

        Log.i("Error caught", e.getMessage());
        e.printStackTrace();

    }
/*
    buildSecond = new int[splitSecond.length];

    for (int i = 0; i <= splitSecond.length; i++) {
        for (int j = 0; j <= 9; j++) {
            if (j == splitSecond[i]) {

                buildSecond[i] = numbers[j];

            }
        }
    }*/

    // original code to display single numbers - worked
    //imageViewFirstNumber.setImageResource(numbers[i]);

    //imageViewSecondNumber.setImageResource(numbers[i]);

}

Из всего, что я видел, этот код должен по крайней мере создать файл .png в каталоге drawable (называемом 72.png, если это было сгенерированное число. Iя знаю эту строку -

imageViewFirstNumber.setImageBitmap(builtFirst);

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

Я также знаю, что -

if (buildFirst.length > 1) {

        for (int i = 1; i < buildFirst.length; i++) {

            canvas.drawBitmap(buildFirst[i], 0, 0, null);
            canvas.drawBitmap(builtFirst, new Matrix(), null);
            newFile = newFile + buildFirst[i].toString();

        }
    }

Это будет просто кучи одного числового изображения поверх другого, я думаю, если я использую buildFirst[i].getwidth * i, в качестве параметра 'left' будетпоместите изображения справа от последнего, но я хотел бы иметь возможность показать любое сгенерированное изображение, а затем обработать уточнения после. На данный момент я получаю только номерной файл по умолчанию, отображаемый после генерации суммы.

Мой обработчик ошибок перехватывает исключение FileNotFoundException в этой строке кода -

Bitmap builtFirst = Bitmap.createBitmap(buildFirst[0].getWidth(), buildFirst[0].getHeight(), buildFirst[0].getConfig());

Я полагаю, это связано с тем, что buildFirst[0] является 'android.graphics.Bitmap@1852540c' счто-то похожее в [1] (генерируется двухзначное число), разве этот процесс не может быть выполнен с файлами .png? Если это так, как я могу объединить их, сохранив прозрачные свойства исходных файлов .png? возможно, есть лучший способ заполнить исходный массив растровых изображений?

Как мне разрешить этот шаг обработки изображений?

1 Ответ

0 голосов
/ 08 ноября 2019

2 дня проб и ошибок, наконец, попали в решение.

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

Bitmap builtFirst = Bitmap.createBitmap(500 * splitFirst.length, 700, ARGB_8888);
    Canvas canvas = new Canvas(builtFirst);

    if (buildFirst.length > 1) {

        for (int i = 0; i < buildFirst.length; i++) {

            canvas.drawBitmap(buildFirst[i], 300 * i, 0, null);
            canvas.drawBitmap(builtFirst, new Matrix(), null);

        }
    }

imageViewFirstNumber.setImageBitmap(builtFirst);
...