Автоматическое решение проблемы сборки Android. Ошибка: пиксели кадра должны быть либо сплошными, либо прозрачными (не промежуточные альфа). - Найден в пикселе № 4 по верхнему краю

Android Studio (с использованием SDK 19, 21 или 22) показывает ошибку, которую Eclipse ADT (с использованием SDK 19) не делает:

Ошибка: изображение 9-патчей D:\Workspaces....\res\drawable-hdpi\btn_bg_common_press.9.png искажено. Ошибка: пиксели кадра должны быть либо сплошными, либо прозрачными (не промежуточные альфа). - Найден в пикселе № 4 по верхнему краю.

Или другая ошибка:

Ошибка: галочки в прозрачной рамке должны быть черного или красного цвета.

оба в aapt

Ошибка: Ошибка: com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: обрабатывать 'команду'E:\Android\sdk-Android-Studio\build-tools\19.1.0\aapt.exe'' завершено с ненулевым значением выхода 42

btn_bg_common_press.9.png

Пример файла выше, но есть более 20 таких файлов, которые работали хорошо.

Как сделать, чтобы Android Studio или Gradle пропустили эту ошибку и не потерпели неудачу, не изменяя эти файлы один за другим?

Если это невозможно с Gradle, какой инструмент командной строки можно использовать, чтобы заменить все прозрачные пиксели непрозрачными?

Файл build.gradle для модуля приложения (где ресурсы) находится ниже.

Я пробовал как с SDK 19 и SDK 21, так и инструменты сборки 19.1, 21.1.2, 22.

Аналогичная проблема в AOSP, выпуск 159464: Android-студия: mergeDebugResources FAILED при импорте проекта 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 находятся по адресу https://android.googlesource.com/platform/tools/build/+/master.

4 ответа

Решение

Как автоматически решить проблему (без проверки всех изображений в разных разрешениях)

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

Предлагаемая альтернатива

Поскольку форма очень проста, вам лучше удалить все варианты этого файла (экономя место, время и головную боль в процессе) и создать /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>

Ты можешь использовать dimen а также color ресурсы вместо жестко закодированных значений. Кроме того, вы можете добавить padding элемент внутри shape

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

и / или обернуть shape элемент внутри 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>

Если вы сделаете это, то в drawable будет подразумеваться заполнение, и вам не придется устанавливать его при оформлении виджетов. Поскольку у вас есть несколько отображаемых состояний для кнопки, я предлагаю вам преобразовать их все в XML, чтобы убедиться, что толщина линий и углы совпадают.

Несмотря на название корневого элемента <shape> на самом деле раздувает GradientDrawable (это означает, что вы можете заполнить его градиентом вместо сплошного цвета). Обзор GradientDrawable документы для всех его вариантов. Никогда не используйте ShapeDrawable программно, это просто не работает.

Анализ 9-патчей

Рассмотрим три следующих увеличенных изображения.

Девять патчей

Кандидат № 1 из девяти патчей. Он зарезервировал 1 пиксель на каждой стороне для спецификации растяжения и заполнения. Этот будет вести себя как обычное растровое изображение при растяжении. Если ширина будет больше, чем высота, то толщина границ будет по бокам. Граница будет масштабироваться пропорционально.

Кандидат № 2 также состоит из девяти патчей и на самом деле говорит, что собирается растянуть все, кроме границы в 1 пиксель, и будет иметь отступ 3 пикселя с каждой стороны. У него будет хорошая четкая граница в 1 пиксель при растяжении.

Кандидат № 3 НЕ является девяти патчем. Он масштабируется так же, как #1.

Теперь давайте взглянем на увеличенную версию изображения, которое вы включили в OP:

Увеличенное изображение от OP

Как видите, это не патч из девяти, поэтому он не будет интерпретироваться как единое целое, и инструменты сборки достаточно любезны, чтобы предупредить вас об этом. Даже если бы старые инструменты сборки были более щадящими и добавляли прозрачные 1px с каждой стороны для вас, результат мог бы вести себя как обычное растровое изображение, то есть при растяжении он выглядел бы как образец A вместо ожидаемого результата B.

Сравнение растрового изображения и патча из девяти

Вот еще чтение на девяти патчах. Это объясняет, для чего используются дополнительные 1 пиксель на каждой стороне.

Данный пример не является изображением из 9 патчей, как было сказано.

Если вы не хотите изменять каждый ресурс, чтобы преобразовать его в действительный ресурс исправления 9, вы можете попробовать удалить ".9" в названии ресурса. Таким образом, поведение должно быть таким же, и вы не получите ошибок сборки.

В Android теперь есть два PNG-дробилки: AAPT и Java. Чтобы игнорировать ошибку PNG в процессе сборки, вы можете заставить Gradle build использовать старый AAPT, установив следующую строку в вашем файле build.gradle:

android.aaptOptions.useAaptPngCruncher = true

Тем не менее, это может привести к той же ошибке, что и инструмент AAPT из последнего SDK, возможно, проверяет и эту ошибку. Итак, у вас есть два варианта:

  • Найдите более старый AAPT, например, <путь SDK>/build-tools/17.0.0/aapt, перезапишите ваш текущий AKT SDK этим старым. Ваши проблемы со сборкой теперь могут быть решены. Если это не работает, попробуйте следующий вариант.

  • Напишите простой сценарий Bash или Perl, назовите его "aapt" и поместите в свою текущую папку инструментов сборки SDK. Этот сценарий вызовет старую версию 17 AAPT для вашей *9.png и будет использовать новую AAPT для всего остального. Смотрите этот ответ переполнения стека для образца сценария.

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

Без ошибок

С ошибкой

Другие вопросы по тегам