关于Android VectorDrawable xml 转为SVG并修改

前言

一般遇到客户要求修改xml 文件VectorDrawable 资源, 需要客户提供图标, 当客户无法提供图标时,就可以参考此篇文章对原图标进行修改

将xml 转为SVG图片

首先需要有一个svg图片作为参考, 国内svg下载网址可以去阿里巴巴图标库下载https://www.iconfont.cn/

打开下载后的svg格式如下

svn格式.png

而VectorDrawable xml 格式如下

xml格式.png

  1. 将我们参考的svg图片复制一份, 重命名为我们要转化的xml文件名字

  2. width/height 同步, viewBox 后两个参数同步android:viewportWidth/viewportHeight 如上需要修改成

    width=“12” height=“15” viewBox=“0 0 12 15”

  3. 将 android:pathData 信息复制到 path -> d, android:fillColor 修改至 fill, 多个path 也是如此, 注意修改fill

效果如下

修改后的svg.png

用浏览器打开, 推荐用Microsoft Edge, 图标尺寸过小

### 换 Drawable 图片至 XXHDPI 分辨率 为了确保 Android 应用中的图片能够适配不同的屏幕密度,特别是针对 `xxhdpi` 的分辨率需求,可以通过以下方法实现: #### 方法一:手动调整图片尺寸 开发者可以在设计阶段准备高质量的原始素材,通过图形编辑工具(如 Photoshop 或 GIMP)将其按比例缩小到适合 `xxhdpi` 寺庙所需的尺寸。通常情况下,对于标准图标或其他 UI 元素,推荐的比例为 3:1(即每像素对应设备上的三个物理像素)。这意味着如果目标显示区域宽度为 48dp,则对应的 `xxhdpi` 文件应具有 \(48 \times 3 = 144\) 像素的实际宽度。 此过程需注意保持原图质量以防止因压缩而导致清晰度下降[^1]。 #### 方法二:利用矢量图形 (Vector Drawables) 相比于传统的基于像素点阵式的 PNG/JPG 格式文件,在现代开发实践中更提倡采用 SVG 形式的向量绘图资源(VectorDrawables),因为它们天生具备无限缩放能力而不会损失细节精度。只需定义一次即可适用于各种 DPI 类型而不必担心匹配问题。 要在项目里启用 VectorDrawable 支持库,请确认 build.gradle 中已加入相应依赖项: ```gradle implementation 'androidx.vectordrawable:vectordrawable-animated:1.1.0' ``` 接着可以直接放置 .xml 结构描述符于 res/drawable/ 下面作为常规 drawable 使用[^4]: ```xml <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"> <path android:pathData="M7,9h10v2H7zm0,4h10v2H7z"/> </vector> ``` 以上代码片段展示了一个简单的路径绘制例子,它会自动适应任何指定的目标 dpi 设置包括但不限于 xxhdpi. #### 方法三:动态生成 Bitmap 重新保存 假如某些特殊场景下无法提前预知确切的需求或者希望完全自动化处理整个流程的话,也可以考虑编程方式完成这项工作。下面给出一段 Kotlin 实现示例演示如何加载一张 bitmap 后再按照特定倍数放大后再存储回磁盘: ```kotlin fun resizeBitmapAndSave(context: Context, originalFileUri: Uri, scaleFactor: Float): File { val inputStream = context.contentResolver.openInputStream(originalFileUri) ?: throw IOException("Cannot open input stream") // Decode sample size based on required scale factor. var options = BitmapFactory.Options() options.inJustDecodeBounds = true BitmapFactory.decodeStream(inputStream, null, options) val width = Math.round(options.outWidth * scaleFactor).toInt() val height = Math.round(options.outHeight * scaleFactor).toInt() inputStream.close() // Close after getting bounds. inputStream = context.contentResolver.openInputStream(originalFileUri)!! options = BitmapFactory.Options().apply { inSampleSize = calculateInSampleSize(this, width, height) } val resizedBitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeStream(inputStream), width, height, false) inputStream.close() // Save new file into cache dir or external storage depending upon your requirement. val outputFile = File(context.cacheDir, "resized_image.png") val outputStream = FileOutputStream(outputFile) resizedBitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream) outputStream.flush() outputStream.close() return outputFile } private fun calculateInSampleSize(options: BitmapFactory.Options, reqWidth: Int, reqHeight: Int): Int { // Raw height and width of image val height = options.outHeight val width = options.outWidth var inSampleSize = 1 if (height > reqHeight || width > reqWidth) { val halfHeight = height / 2 val halfWidth = width / 2 while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) { inSampleSize *= 2 } } return inSampleSize } ``` 上述函数接受一个 URI 和期望的缩放因子作为输入参数,返回经过调整后的临时文件对象。需要注意的是这里仅作示范用途,在实际应用前可能还需要进一步优化内存管理等方面的内容.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值