自动解决Android构建错误:帧像素必须是固态或透明的(不是中间的alphas)。-在顶部边缘的第4像素处找到

时间:2023-01-22 14:26:13

Android Studio (using SDK 19, 21 or 22) shows an error that Eclipse ADT (using SDK 19) does not:

Android Studio(使用SDK 19、21或22)显示了一个Eclipse ADT(使用SDK 19)没有的错误:

Error:9-patch image D:\Workspaces....\res\drawable-hdpi\btn_bg_common_press.9.png malformed. Error:Frame pixels must be either solid or transparent (not intermediate alphas). - Found at pixel #4 along top edge.

错误:9-patch形象D:\工作区.... \ res \ drawable-hdpi \ btn_bg_common_press.9。png畸形。错误:帧像素必须是固态或透明的(不是中间的alphas)。-在顶部边缘的第4像素处找到。

Or another error:

或另一个错误:

Error:Ticks in transparent frame must be black or red.

错误:透明框中的刻度必须是黑色或红色。

both within aapt

在aapt

Error:Error: com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command 'E:\Android\sdk-Android-Studio\build-tools\19.1.0\aapt.exe'' finished with non-zero exit value 42

错误:com. Android . idea .common. Process . processexception: org.gradle.process.internal.ExecException: Process 'command: Process '命令'E:\ sdk- androidd - studio \build-tools\19.1.0\aapt。exe "以非零出口值42结束

自动解决Android构建错误:帧像素必须是固态或透明的(不是中间的alphas)。-在顶部边缘的第4像素处找到

Example of file is above, but there are 20+ such files that worked well.

文件示例在上面,但是有20多个这样的文件可以很好地工作。

How do I make Android Studio or Gradle skip this error and not fail without having to modify those files one-by-one?

如何使Android Studio或Gradle跳过这个错误,并且在不修改这些文件的情况下不会失败呢?

If it is not possible with Gradle, what command-line tool could I use to replace all transparent pixel with non-transparent?

如果不能使用Gradle,我可以使用什么命令行工具将所有透明像素替换为非透明像素?

The build.gradle file for the application module (where resources are) is below.

构建。下面是应用程序模块的等级文件(资源在其中)。

I have tried both with SDK 19 and SDK 21 and build tools 19.1, 21.1.2, 22.

我已经尝试了SDK 19和SDK 21,并构建了工具19.1,21.1.2,22。

A similar issue on AOSP, Issue 159464: Android studio: mergeDebugResources FAILED when importing Eclipse project.

AOSP上的一个类似问题是,第159464期:Android studio: mergeDebugResources在导入Eclipse项目时失败。

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.1.+'
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

//---
task wrapper(type: Wrapper) {
    gradleVersion = '2.2.1'
}

apply plugin: 'com.android.application'

dependencies {
    compile fileTree(dir: 'libs', include: '*.jar')
    compile project(':afinal')
    compile 'com.android.support:appcompat-v7:19.0.+'
    //compile 'com.android.support:appcompat-v7:21.0.+'
}

//---
android {
    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }
    }

    compileSdkVersion 19
    buildToolsVersion "19.1.0"
    //compileSdkVersion 21
    //buildToolsVersion "21.1.2"
    //compileSdkVersion Integer.parseInt(project.COMPILE_SDK_VERSION)
    //buildToolsVersion project.BUILD_TOOLS_VERSION

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
            zipAlignEnabled true
            //signingConfig signingConfigs.release
        }
        debug {
            zipAlignEnabled true
        }
    }

    lintOptions {
        //checkReleaseBuilds false
        // Or, if you prefer, you can continue to check for errors in release builds,
        // but continue the build even when errors are found:
        abortOnError false // false also required by https://wiki.jenkins-ci.org/display/JENKINS/Android+Lint+Plugin
    }
}//android

Android Gradle plugins sources are at https://android.googlesource.com/platform/tools/build/+/master.

Android等级插件的来源是https://android.googlesource.com/platform/tools/build/+/master。

4 个解决方案

#1


8  

How automatically solve the issue (without checking all images in different resolutions)

如何自动解决问题(不检查所有不同分辨率的图像)

Not possible. Since you want the .png to behave like a nine-patch (expand along the edges, not stretch the whole bitmap), you're going to have to format them as such ergo you have to modify the files.

不可能的。由于您希望.png的行为像一个9补丁(沿着边缘展开,而不是扩展整个位图),您将不得不对它们进行格式化,因此您必须修改文件。

Proposed alternative

提出了选择

Since the shape is so simple you'd be better off deleting all variants of this file (saving space, time and headache in the process) and create /res/drawable/btn_bg_common_press.xml drawable with following contents:

由于该形状非常简单,所以最好删除该文件的所有变体(节省空间、时间和过程中的麻烦),并创建/res/drawable/btn_bg_common_press。xml可绘图,内容如下:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <corners android:radius="16dp"/>
    <solid android:color="#ccc"/>
    <stroke
        android:color="#0c0"
        android:width="2dp"/>
</shape>

You can use dimen and color resources instead of hardcoded values. Additionally you might want to add the padding element inside shape

您可以使用dimen和color资源,而不是硬编码值。此外,您可能希望在shape中添加填充元素

<shape...>
    <padding
        android:top="8dp"
        android:left="8dp"
        android:bottom="8dp"
        android:right="8dp"/>
</shape>

and/or wrap the shape element inside an inset element.

和/或将形状元素封装在一个inset元素中。

<inset
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:insetTop="8dp"
    android:insetLeft="8dp"
    android:insetBottom="8dp"
    android:insetRight="8dp">
    <shape...>
</inset>

If you do that, the drawable will have implied padding and you won't have to set it when styling widgets. Since you have multiple state drawables for the button I suggest you convert all of them to XML to make sure the line thickness and corners match.

如果您这样做,那么drawable将具有隐含的填充,您不必在样式化小部件时设置它。由于该按钮有多个状态可绘制项,所以我建议您将它们全部转换为XML,以确保行厚和角的匹配。

Despite the root element's name the <shape> actually inflates to GradientDrawable (meaning you can fill it with gradient instead of solid color). Review GradientDrawable docs for all its options. Do not ever use ShapeDrawable programmatically, it just doesn't work.

尽管根元素的名称是 ,但它实际上会膨胀为gradient - drawentdrawable(意思是您可以用gradient代替solid颜色来填充它)。查看渐变的文档,查看它的所有选项。不要以编程的方式使用ShapeDrawable,它只是不起作用。

Analyzing 9-patches

分析9-patches

Consider the three following enlarged images.

考虑以下三个放大的图像。

自动解决Android构建错误:帧像素必须是固态或透明的(不是中间的alphas)。-在顶部边缘的第4像素处找到

Candidate #1 is a nine-patch. It has reserved 1px on each side for stretch and padding specification. This one will behave as an ordinary bitmap when stretched. If the width will be greater than height, so will the border thickness on sides. The border will scale proportionally.

候选1是9个补丁。每边预留1px用于拉伸和填充规格。当拉伸时,这个将表现为一个普通的位图。如果宽度大于高度,则边沿厚度也大于宽度。边界将按比例扩大。

Candidate #2 is also a nine-patch and is actually saying it's going to stretch everything besides 1px border and will have implied padding of 3px on each side. It will have a nice crisp 1px border when stretched.

候选2也是一个9个补丁,它实际上说除了1px边界外,它将扩展所有东西,并且每条边都有3px的填充。拉伸时,它会有一个清晰的1px边框。

Candidate #3 is NOT a nine-patch. It scales the same way as #1.

候选3不是一个九补丁。它的大小和#1一样。

Now let's take a look at enlarged version of the image you included in OP:

现在我们来看看OP中包含的放大版本:

自动解决Android构建错误:帧像素必须是固态或透明的(不是中间的alphas)。-在顶部边缘的第4像素处找到

As you can see it's not a nine-patch, so it won't get interpreted as one and the build tools are kind enough to warn you of that. Even if older build tools were more forgiving and added transparent 1px on each side for you, the result would have behaved like an ordinary bitmap, meaning when stretched it would look like specimen A instead of expected result specimen B.

正如您所看到的,它不是一个9补丁,所以它不会被解释为1,构建工具足够友好地提醒您这一点。即使旧的构建工具更宽容,并且为你在两边增加了透明的1px,结果也会像一个普通的位图,这意味着当拉伸它时,它会看起来像样本A而不是预期的样本B。

自动解决Android构建错误:帧像素必须是固态或透明的(不是中间的alphas)。-在顶部边缘的第4像素处找到

Here's more reading on nine-patches. This explains what the extra 1px on each side is used for.

这里有更多关于9个补丁的阅读。这就解释了两边额外的1px的用途。

#2


7  

The example given is not a 9 patch image, as it has been told.

所给出的示例并不是一个9补丁映像,正如它被告知的那样。

If you don't want to modify each resource in order to transform it to a valid 9 patch resource, you could try removing ".9" in the resource's name. This way, the behavior should be the same, and you won't get build errors.

如果您不想修改每个资源以将其转换为有效的9个补丁资源,您可以尝试删除它。9“以资源的名义。这样,行为应该是相同的,并且不会产生构建错误。

#3


3  

Android now has two PNG crunchers, the AAPT one and a Java one. To ignore the PNG error in build process, you can force Gradle build to use the old AAPT by setting the below line in your build.gradle file:

Android现在有两个PNG处理器,一个是AAPT,一个是Java。要忽略构建过程中的PNG错误,可以通过在构建中设置以下行来强制Gradle构建使用旧的AAPT。gradle文件:

android.aaptOptions.useAaptPngCruncher = true

Still this may give you the same error, as the AAPT tool from the latest SDK might be checking for this error too. So you have two options:

尽管如此,这可能会给您带来相同的错误,因为来自最新SDK的AAPT工具可能也在检查这个错误。所以你有两个选择:

  • Find an older AAPT, for example, <SDK path>/build-tools/17.0.0/aapt, overwrite your current SDK AAPT with this old one. Your build issues may now be resolved. If this doesn't work, try the below option.

    找到一个较老的AAPT,例如 /build-tools/17.0.0/ AAPT,用这个旧的SDK覆盖当前的SDK。您的构建问题现在可以解决了。如果这不起作用,请尝试下面的选项。

  • Write a simple Bash or Perl script, name it "aapt" and put it in your current SDK build-tools folder. This script will call the old version 17 AAPT for your *9.png, and use the new AAPT for everything else. See this Stack Overflow answer for a sample script.

    编写一个简单的Bash或Perl脚本,将其命名为“aapt”,并将其放入当前的SDK构建工具文件夹中。这个脚本将为您的*9调用旧版本17 AAPT。png,然后用新的AAPT来做其他的事情。查看示例脚本的堆栈溢出答案。

#4


0  

To solve this problem ensure that you fill all edges with black or red points. This solved my problem for all SDK versions. If you don't want to scale vertically or horizontally or both of them, just fill all edges. In this case the image doesn't scale.

要解决这个问题,请确保所有的边缘都是黑色或红色的点。这解决了所有SDK版本的问题。如果你不想垂直或水平缩放或者两者都缩放,只需要填充所有的边。在这种情况下,图像不会缩放。

Without error

没有错误

With malformed error

畸形的错误

#1


8  

How automatically solve the issue (without checking all images in different resolutions)

如何自动解决问题(不检查所有不同分辨率的图像)

Not possible. Since you want the .png to behave like a nine-patch (expand along the edges, not stretch the whole bitmap), you're going to have to format them as such ergo you have to modify the files.

不可能的。由于您希望.png的行为像一个9补丁(沿着边缘展开,而不是扩展整个位图),您将不得不对它们进行格式化,因此您必须修改文件。

Proposed alternative

提出了选择

Since the shape is so simple you'd be better off deleting all variants of this file (saving space, time and headache in the process) and create /res/drawable/btn_bg_common_press.xml drawable with following contents:

由于该形状非常简单,所以最好删除该文件的所有变体(节省空间、时间和过程中的麻烦),并创建/res/drawable/btn_bg_common_press。xml可绘图,内容如下:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <corners android:radius="16dp"/>
    <solid android:color="#ccc"/>
    <stroke
        android:color="#0c0"
        android:width="2dp"/>
</shape>

You can use dimen and color resources instead of hardcoded values. Additionally you might want to add the padding element inside shape

您可以使用dimen和color资源,而不是硬编码值。此外,您可能希望在shape中添加填充元素

<shape...>
    <padding
        android:top="8dp"
        android:left="8dp"
        android:bottom="8dp"
        android:right="8dp"/>
</shape>

and/or wrap the shape element inside an inset element.

和/或将形状元素封装在一个inset元素中。

<inset
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:insetTop="8dp"
    android:insetLeft="8dp"
    android:insetBottom="8dp"
    android:insetRight="8dp">
    <shape...>
</inset>

If you do that, the drawable will have implied padding and you won't have to set it when styling widgets. Since you have multiple state drawables for the button I suggest you convert all of them to XML to make sure the line thickness and corners match.

如果您这样做,那么drawable将具有隐含的填充,您不必在样式化小部件时设置它。由于该按钮有多个状态可绘制项,所以我建议您将它们全部转换为XML,以确保行厚和角的匹配。

Despite the root element's name the <shape> actually inflates to GradientDrawable (meaning you can fill it with gradient instead of solid color). Review GradientDrawable docs for all its options. Do not ever use ShapeDrawable programmatically, it just doesn't work.

尽管根元素的名称是 ,但它实际上会膨胀为gradient - drawentdrawable(意思是您可以用gradient代替solid颜色来填充它)。查看渐变的文档,查看它的所有选项。不要以编程的方式使用ShapeDrawable,它只是不起作用。

Analyzing 9-patches

分析9-patches

Consider the three following enlarged images.

考虑以下三个放大的图像。

自动解决Android构建错误:帧像素必须是固态或透明的(不是中间的alphas)。-在顶部边缘的第4像素处找到

Candidate #1 is a nine-patch. It has reserved 1px on each side for stretch and padding specification. This one will behave as an ordinary bitmap when stretched. If the width will be greater than height, so will the border thickness on sides. The border will scale proportionally.

候选1是9个补丁。每边预留1px用于拉伸和填充规格。当拉伸时,这个将表现为一个普通的位图。如果宽度大于高度,则边沿厚度也大于宽度。边界将按比例扩大。

Candidate #2 is also a nine-patch and is actually saying it's going to stretch everything besides 1px border and will have implied padding of 3px on each side. It will have a nice crisp 1px border when stretched.

候选2也是一个9个补丁,它实际上说除了1px边界外,它将扩展所有东西,并且每条边都有3px的填充。拉伸时,它会有一个清晰的1px边框。

Candidate #3 is NOT a nine-patch. It scales the same way as #1.

候选3不是一个九补丁。它的大小和#1一样。

Now let's take a look at enlarged version of the image you included in OP:

现在我们来看看OP中包含的放大版本:

自动解决Android构建错误:帧像素必须是固态或透明的(不是中间的alphas)。-在顶部边缘的第4像素处找到

As you can see it's not a nine-patch, so it won't get interpreted as one and the build tools are kind enough to warn you of that. Even if older build tools were more forgiving and added transparent 1px on each side for you, the result would have behaved like an ordinary bitmap, meaning when stretched it would look like specimen A instead of expected result specimen B.

正如您所看到的,它不是一个9补丁,所以它不会被解释为1,构建工具足够友好地提醒您这一点。即使旧的构建工具更宽容,并且为你在两边增加了透明的1px,结果也会像一个普通的位图,这意味着当拉伸它时,它会看起来像样本A而不是预期的样本B。

自动解决Android构建错误:帧像素必须是固态或透明的(不是中间的alphas)。-在顶部边缘的第4像素处找到

Here's more reading on nine-patches. This explains what the extra 1px on each side is used for.

这里有更多关于9个补丁的阅读。这就解释了两边额外的1px的用途。

#2


7  

The example given is not a 9 patch image, as it has been told.

所给出的示例并不是一个9补丁映像,正如它被告知的那样。

If you don't want to modify each resource in order to transform it to a valid 9 patch resource, you could try removing ".9" in the resource's name. This way, the behavior should be the same, and you won't get build errors.

如果您不想修改每个资源以将其转换为有效的9个补丁资源,您可以尝试删除它。9“以资源的名义。这样,行为应该是相同的,并且不会产生构建错误。

#3


3  

Android now has two PNG crunchers, the AAPT one and a Java one. To ignore the PNG error in build process, you can force Gradle build to use the old AAPT by setting the below line in your build.gradle file:

Android现在有两个PNG处理器,一个是AAPT,一个是Java。要忽略构建过程中的PNG错误,可以通过在构建中设置以下行来强制Gradle构建使用旧的AAPT。gradle文件:

android.aaptOptions.useAaptPngCruncher = true

Still this may give you the same error, as the AAPT tool from the latest SDK might be checking for this error too. So you have two options:

尽管如此,这可能会给您带来相同的错误,因为来自最新SDK的AAPT工具可能也在检查这个错误。所以你有两个选择:

  • Find an older AAPT, for example, <SDK path>/build-tools/17.0.0/aapt, overwrite your current SDK AAPT with this old one. Your build issues may now be resolved. If this doesn't work, try the below option.

    找到一个较老的AAPT,例如 /build-tools/17.0.0/ AAPT,用这个旧的SDK覆盖当前的SDK。您的构建问题现在可以解决了。如果这不起作用,请尝试下面的选项。

  • Write a simple Bash or Perl script, name it "aapt" and put it in your current SDK build-tools folder. This script will call the old version 17 AAPT for your *9.png, and use the new AAPT for everything else. See this Stack Overflow answer for a sample script.

    编写一个简单的Bash或Perl脚本,将其命名为“aapt”,并将其放入当前的SDK构建工具文件夹中。这个脚本将为您的*9调用旧版本17 AAPT。png,然后用新的AAPT来做其他的事情。查看示例脚本的堆栈溢出答案。

#4


0  

To solve this problem ensure that you fill all edges with black or red points. This solved my problem for all SDK versions. If you don't want to scale vertically or horizontally or both of them, just fill all edges. In this case the image doesn't scale.

要解决这个问题,请确保所有的边缘都是黑色或红色的点。这解决了所有SDK版本的问题。如果你不想垂直或水平缩放或者两者都缩放,只需要填充所有的边。在这种情况下,图像不会缩放。

Without error

没有错误

With malformed error

畸形的错误