以编程方式合并 png 文件
Merging png files programmatically
我知道这个主题有很多帖子,我已经用它们走到了这一步,但我觉得我需要一些额外的东西来克服困难,因为 none 其中演示了数组在这个过程中的使用.
我正在构建一个适合儿童的数学应用程序,因此,我使用 .png 文件来显示相关数字。我在可绘制文件夹中有 png 格式的数字 0-9(透明属性所需),并且测试仅使用数字 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]);
}
根据我所看到的,这段代码至少应该在 drawable 目录中构建一个 .png 文件(如果那是生成的数字,则称为 72.png。我知道这一行 -
imageViewFirstNumber.setImageBitmap(builtFirst);
不会显示该文件。我不确定如何引用新生成的文件,但更大的问题是 newFile 不在可绘制文件夹中。
我也知道 -
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] 中的内容类似(生成了 2 位数字),这个过程不能用 .png 文件完成吗?如果是这样,我如何在保持原始 .png 文件的透明属性的同时合并它们?也许有更好的方法来填充原始位图数组?
如何解决这个图像处理步骤?
2 天的反复试验终于找到了解决方案。
不需要压缩文件或编写任何新文件或使用任何位图作为模板,也不需要将新的可绘制对象作为资源引用(而只是应用创建的位图变量)是这里的问题。
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);
我知道这个主题有很多帖子,我已经用它们走到了这一步,但我觉得我需要一些额外的东西来克服困难,因为 none 其中演示了数组在这个过程中的使用.
我正在构建一个适合儿童的数学应用程序,因此,我使用 .png 文件来显示相关数字。我在可绘制文件夹中有 png 格式的数字 0-9(透明属性所需),并且测试仅使用数字 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]);
}
根据我所看到的,这段代码至少应该在 drawable 目录中构建一个 .png 文件(如果那是生成的数字,则称为 72.png。我知道这一行 -
imageViewFirstNumber.setImageBitmap(builtFirst);
不会显示该文件。我不确定如何引用新生成的文件,但更大的问题是 newFile 不在可绘制文件夹中。
我也知道 -
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] 中的内容类似(生成了 2 位数字),这个过程不能用 .png 文件完成吗?如果是这样,我如何在保持原始 .png 文件的透明属性的同时合并它们?也许有更好的方法来填充原始位图数组?
如何解决这个图像处理步骤?
2 天的反复试验终于找到了解决方案。
不需要压缩文件或编写任何新文件或使用任何位图作为模板,也不需要将新的可绘制对象作为资源引用(而只是应用创建的位图变量)是这里的问题。
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);