Automatically solve Android build Error:Frame pixels must be either solid or transparent (not intermediate alphas). - Found at pixel #4 along top edge

若如初见. 提交于 2019-11-28 19:37:14

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.

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:

<?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

<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
    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.

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.

Analyzing 9-patches

Consider the three following enlarged images.

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.

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.

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

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

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.

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

Jofre Mateu

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

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.

ashoke

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.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:

  • 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.

  • 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.

sakit

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.

Without error

With malformed error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!