将android资源位图批量转换为不同密度的工具[关闭]

2024-02-12

我需要在 Android 上发布后支持不同的显示密度

开发期间可绘制的 hdpi已增长至 160 个 png(其中 20 个,其中 9 个补丁)资源

我现在需要将所有这些位图转换为平均密度指数、平均密度指数(布局和可绘制 XML 已经很好了,避免在 LayoutInflater 上引发 OOM

有没有适合批量转换所有这些位图的工具?


这是一个简单的脚本,用于从高分辨率的 Android 可绘制对象创建较低分辨率的 Android 可绘制对象。

例如,给定一批 -xhdpi 图像,它可以生成 -hdpi 和 -mdpi 图像。

使用此脚本,可以从创作工具仅导出最高分辨率的图稿,然后使用一些批处理命令创建较低分辨率的版本。

脚本用法:

drawable_convert.py -d res/drawable-mdpi -d res/drawable-hdpi res/drawable-xhdpi-v14/*.png

这将从 xhdpi 中获取每个 png 文件,并将较低分辨率的版本放入 mdpi 和 hdpi 文件夹中。

http://kmansoft.com/2012/05/23/scale-android-drawables-with-a-script/ http://kmansoft.com/2012/05/23/scale-android-drawables-with-a-script/
原始脚本,https://gist.github.com/2771791 https://gist.github.com/2771791


脚本本身,以避免依赖 github gist/原始博客文章。
name 可绘制_convert.py

#!/usr/bin/python

import sys
import argparse
import os
import re

'''
A simple script to create lower-resolution Android drawables from higher-resolution ones.

For example, given a batch of -xhdpi images, you can generate -hdpi and -mdpi images.

This makes it possible to only export highest-resolution artwork from image authoring tools, and
automate the rest.

Usage:

   drawable_convert.py -d res/drawable-mdpi -d res/drawable-hdpi res/drawable-xhdpi-v14/select*.png

   ... will take select*.png from xhdpi and place versions into mdpi and hdpi folders.

   Correct resize ratios are computed based on resource directory names.

   Actual scaling is done by ImageMagick's convert command.
'''

class Converter:
    def __init__(self, dstList):
        print u'Dst list: {0}'.format(dstList)
        self.mDstList = dstList

    def convert(self, src):
        for dstpath in self.mDstList:
            (srcpath, srcname) = os.path.split(src)
            dst = os.path.join(dstpath, srcname)
            self.convertOne(src, dst)

    def convertOne(self, src, dst):
        print u'\n*****\n{0} to {1}\n*****\n'.format(src, dst)
        '''
        Determine relative density
        '''
        srcDpi = self.getDpi(src)
        dstDpi = self.getDpi(dst)

        if srcDpi < dstDpi:
            print u'NOT converting from {0}dpi to {1}dpi'.format(srcDpi, dstDpi)
        else:
            factor = dstDpi*100/srcDpi
            print u'Converting from {0}dpi to {1}dpi, {2}%'.format(srcDpi, dstDpi, factor)
            cmd = u'convert -verbose "{0}" -resize "{2}%x{2}%" "{1}"'.format(src, dst, factor)
            os.system(cmd)

    def getDpi(self, f):
        p = os.path.dirname(f)
        if re.match('.*drawable.*\\-mdpi.*', p):
            return 160
        elif re.match('.*drawable.*\\-hdpi.*', p):
            return 240
        elif re.match('.*drawable.*\\-xhdpi.*', p):
            return 320
        else:
            raise ValueError(u'Cannot determine densitiy for {0}'.format(p))

if __name__ == "__main__":
    '''
    Parse command line arguments
    '''
    parser = argparse.ArgumentParser(description='Converts drawable resources in Android applications')
    parser.add_argument('-d', dest='DST', action='append', required=True, help='destination directory')
    parser.add_argument('src', nargs='+', help='files to convert (one or more)')
    args = parser.parse_args()

    cv = Converter(args.DST)
    for src in args.src:
        cv.convert(src)


'''


if [ $# -lt 1 ] ; then
    echo "Usage: $0 file_list"
    exit 1
fi

for f in $*
do
    echo "File: ${f}"
    convert -verbose "${f}" -resize "75%x75%" "../drawable-hdpi/${f}"
    convert -verbose "${f}" -resize "50%x50%" "../drawable-mdpi/${f}"
done

'''
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将android资源位图批量转换为不同密度的工具[关闭] 的相关文章

  • 使用 Android 前台服务为 MediaPlayer 创建通知

    问题就在这里 我目前正在开发一个应用程序 该应用程序必须提供 A 广播播放器 来自 URL 的 AAC 直播 还有一个播客播放器 来自 URL 的 MP3 流 该应用程序必须能够在后台运行 Android 服务 并通过以下方式向用户公开持续
  • Android SoundPool 堆限制

    我正在使用 SoundPool 加载多个声音剪辑并播放它们 据我所知 它的功能 100 正确 但在 load 调用期间 我的日志中充斥着以下内容 06 09 11 30 26 110 ERROR AudioCache 23363 Heap
  • 共同的偏好不断消失

    我正在使用共享首选项来存储我的应用程序的登录凭据 除了一个用户之外 一切正常 一段时间后 共享偏好似乎会以某种方式重置或清除 我已针对该用户调整了我的应用程序 使其不再清除他的共享偏好设置 这样我就可以确定这不是我的应用程序的错 但即使在这
  • 接近语法错误(代码1)插入Android SQLite

    我正在创建一个通讯录应用程序 用户可以在其中输入姓名 电子邮件地址和号码 我希望将此数据保存在数据库中 但我似乎无法使插入方法起作用 我收到的错误是 android database sqlite SQLiteException near
  • 线程自动利用多个CPU核心?

    假设我的应用程序运行 2 个线程 例如渲染线程和游戏更新线程 如果它在具有多核 CPU 当今典型 的移动设备上运行 我是否可以期望线程在可能的情况下自动分配给不同的核心 我知道底层操作系统内核 Android linux内核 决定调度 我的
  • 在 Android 中使用 DataOutputStream 在 POST 正文中发送特殊字符 (ë ä ï)

    我目前正在开发一个具有大量服务器端通信的 Android 应用程序 昨天 我收到一份错误报告 称用户无法发送 简单 特殊字符 例如 我搜索过但没有找到任何有用的东西 可能重复 没有答案 https stackoverflow com que
  • 如何查找 Android 设备中的所有文件并将它们放入列表中?

    我正在寻求帮助来列出 Android 外部存储设备中的所有文件 我想查找所有文件夹 包括主文件夹的子文件夹 有办法吗 我已经做了一个基本的工作 但我仍然没有得到想要的结果 这不起作用 这是我的代码 File files array file
  • 如何在 sqlite 中将 2 列合并为新列

    我有一个包含 3 列的表 我必须将 2 列中的值按降序排列到一列中 A B C z 1 2 f 5 7 s 9 5 使用此示例 输出会将 B 列和 C 列中的值放入其中 如下所示 A B s 9 f 7 f 5 s 5 z 2 z 1 我当
  • 在我的Android中,当其他应用程序想要录制音频时如何停止录音?

    在我的应用程序中 服务通过 AudioRecord 持续录制音频 当我的应用程序运行时 其他与音频记录相关的应用程序 例如 Google 搜索 无法工作 如何知道何时有其他应用想要录制音频 以便我可以停止录制以释放资源 答案是MediaRe
  • 请求位置更新参数

    这就是 requestLocationUpdates 的样子 我使用它的方式 requestLocationUpdates String provider long minTime float minDistance LocationLis
  • Flutter 深度链接

    据Flutter官方介绍深层链接页面 https flutter dev docs development ui navigation deep linking 我们不需要任何插件或本机 Android iOS 代码来处理深层链接 但它并没
  • ROOM迁移过程中如何处理索引信息

    CODE Entity tableName UserRepo indices Index value id unique true public class GitHubRepo PrimaryKey autoGenerate true p
  • MediaCodec 创建输入表面

    我想使用 MediaCodec 将 Surface 编码为 H 264 使用 API 18 有一种方法可以通过调用 createInputSurface 然后在该表面上绘图来对表面中的内容进行编码 我在 createInputSurface
  • Android构建apk:控制MANIFEST.MF

    Android 构建 APK 假设一个 apk 包含一个库 jar 例如 foo jar 该库具有 META INF MANIFEST MF 这对于它的运行很重要 但在APK中有一个包含签名数据的MANIFEST MF 并且lib jar
  • 如何在不更改手机语言的情况下更改Android应用程序语言?

    我希望用户在应用程序内选择一种语言 选择语言后 我希望字符串使用特定语言 如果我更改手机语言 那么我的应用程序将以设置的语言运行 我无法找到任何在不更改手机语言的情况下设置语言的方法 此外 一旦设置了语言 更改就应该反映出来 有人可以建议一
  • 材质设计图标颜色

    应该是哪种颜色 暗 材质图标 在官方文档上 https www google com design spec style icons html icons system icons https www google com design s
  • 调节麦克风录音音量

    我们正在尝试调整录音时的音量级别 麦克风似乎非常敏感 会接收到很多静电 我们查看了 setVolumeControlStream 但找不到传入其中来控制麦克风的流 将您的音频源设置为 MIC using MediaRecorder Audi
  • 如何创建像谷歌位置历史记录一样的Android时间轴视图?

    我想设计像谷歌位置历史这样的用户界面 我必须为我正在使用的应用程序复制此 UIRecyclerView 每行都是水平的LinearLayout其中包含右侧的图标 线条和视图 该线是一个FrameLayout具有圆形背景和半透明圆圈Views
  • SharedFlow 和 StateFlow 的主要区别

    两者有什么区别共享流 and 状态流 以及如何使用这些MVI建筑学 使用简单更好吗Flow或者这些作为状态和事件 Flow 是冷的 意味着它仅在收集数据时才发出数据 另外Flow不能保存数据 可以把它看成是水在里面流动的管道 Flow中的数
  • 无法运行我的应用程序,要求选择 Android SDK

    今天我已经安装了Android Studio 金丝雀 1 现在我无法运行我的应用程序 将出现以下对话框 我已经通过 文件 gt 项目结构 gt Android SDK 位置 设置了正确的 SDK 位置 期待您的帮助来解决这个问题 警告对话框

随机推荐

  • 在 GWT 单元格表中添加超链接

    我正在尝试在单元格表中添加一个超链接 然后单击该链接我想调用一个方法 使用下面的代码 我在单元格表中正确获得了超链接 但我无法通过单击链接来调用方法 当我单击链接时 它会将我带到上一页 任何解决方案 Hyperlink link new H
  • Excel VBA - 将子菜单添加到自定义右键菜单

    看了很久了 第一次发海报 我有一个带有右键单击功能的表单 可以正常工作 我试图在主右键菜单中添加一个子菜单来分隔一些功能 命令 我需要 想要插入 选择案例 所在的部分 但是 它只显示顶部菜单 不知道从这里去哪里 任何帮助都是极好的 谢谢 附
  • Python读取DOT格式的文件并返回城市名称列表

    嘿大家好 问题是这样的 说实话 这是家庭作业问题 但我只是被困住了 而且已经永远了 我的问题是 由于城市在每行中都有不同的索引位置 我们如何逐行迭代并将城市名称返回到列表中 任何可以让我开始的帮助将不胜感激 我并不懒惰 我已经为此工作了几个
  • 如何从视频中提取方向信息?

    在网上浏览了大量文档后 iPhone 似乎总是以 480x360 的宽高比拍摄视频 并在视频轨道上应用变换矩阵 480x360 可能会改变 但对于给定设备来说始终相同 这是在 iOS 项目中修改 ffmpeg 源并访问矩阵的方法http w
  • python中pandas系列的地板还是天花板?

    我有一个熊猫系列series 如果我想获得元素级下限或上限 是否有内置方法或者我是否必须编写函数并使用 apply 我问是因为数据很大所以我很看重效率 此外 还没有针对 Pandas 包提出这个问题 您可以使用 NumPy 的内置方法来执行
  • App Engine Java API 页面大小

    为什么谷歌决定忽略pageSize参数以及为什么使用不同的页面大小时收集的项目的总体大小不同 这是一个例子 Appsactivity Activities List request service activities list setDr
  • 如何更改 UIView zPosition?

    我不明白如何更改视图的位置 我尝试这样做 但没有任何反应 void viewDidLoad super viewDidLoad UIView view UIView alloc initWithFrame CGRectMake 100 10
  • 如何使用 Clang 从 C++ 字符串生成 AST?

    我正在尝试使用 Clang 操作 C 源代码 但在发现 API 时遇到问题 我想获取一串 C 源代码并从中生成 AST 就像是 auto myAst clang parse auto x 1 1 有一个最小的工作示例吗 您可以尝试下一个代码
  • 为什么添加的子图层没有显示在屏幕截图中?

    我正在尝试找出 iPad 应用程序的某些 iOS 代码中的错误 在我们的一个视图中 我们添加了子图层以产生阴影并确保视图的底部具有圆角边缘 这是我们添加子层的代码 UIBezierPath maskPath UIBezierPath bez
  • 无效的路由名称,已在使用中:“admin_root”(ArgumentError)- ActiveAdmin 安装失败

    I ran rails g active admin install 并得到这个错误 Invalid route name already in use admin root ArgumentError You may have defin
  • 为什么java中所有对象都是动态创建的? [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 在一次采访中我被问到为什么java中的对象是动态创建的 我不明白这个问题 有人可以解释一下吗 此人可能指的是 Java 不像 C 那样知道堆
  • PHP $_SESSION 变量键中的保留字符

    我正在查看 PHP 会话文件的内部表示 我注意到会话密钥由管道字符分隔 在讨论我遇到的问题之前 让我先快速介绍一下会话文件的格式 至少 这是它在我的 Mac 上的格式化方式 10 9 4 PHP 5 4 24 会话文件格式 假设我有以下代码
  • 使用 Javascript 平均时间

    我正在使用 Phonegap 和 JQuery 构建一个应用程序 该应用程序以该格式存储 使用 window localStorage 一组时间 不超过 10 个 HH MM SS mm 列表中有许多 零 时间 例如 00 00 00 00
  • extjs - 自动加载 true 的存储不应在应用程序启动时加载

    我有一个链接到商店的网格autoLoad true 问题是商店会在应用程序启动时加载 即使视图是稍后通过菜单访问时创建的 我已在 Application js 和视图中引用了该存储 但我没有显式地实例化存储或视图 我不知道如何实现仅在视图需
  • 将 TabActivity 菜单与包含的 Activity 菜单合并

    我的应用程序的主要活动是 TabActivity 它包含一个 OptionsMenu 我定义了一些其他活动 进入选项卡 并且我想在每个活动中定义一个菜单 并将其菜单与主菜单合并 是否可以 是的 这是可能的 基本上 您只需将多个 xml 文件
  • 一种用子类组织和加载文件的干净方法

    我有一个父类 它提供用于操作硬件的抽象函数 以及一个充满类的目录 该类是该父类的子类 并提供特定于硬件的实现 例如 x86 函数 ARM 函数 我正在寻找一种 Pythonic 方式来导入目录中的文件并实例化它们 目前 父类位于顶级目录中
  • TensorFlow RuntimeError:在 SavedModel 中找不到与标签服务关联的 MetaGraphDef

    当我使用 simple save 保存模型时 当我尝试加载模型时出现运行时错误 保存的代码是 session Session inputs tf placeholder dtype tf float32 shape None height
  • 使用树状数据进行 pytest 嵌套参数化

    使用 pytest 我尝试测试像树一样的分层场景 让我们以文档结构为例 Document Chapter Paragraph 1 n 1 n 当文档包含多个章节时 一章包含多个段落 当开始测试新文档时 需要运行一些设置代码 当新的章节开始时
  • 改变跨度的类别

    我有两个div 如下所示 我想从div top2更改span s1的类名 但下面的代码不起作用 我怎样才能做到这一点 top1 s1 span myclass old toggleClass myclass new div span cla
  • 将android资源位图批量转换为不同密度的工具[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我需要在 Android 上发布后支持不同的显示密度 开发期间可绘制的 hdpi已增长至 160 个