6.6.2 - Alpha6 - 新增 images.flip 方法 (issue #349)

This commit is contained in:
SuperMonster003
2025-04-12 13:01:59 +08:00
parent 772f96ac78
commit c059154d0e
10 changed files with 81 additions and 9 deletions

View File

@@ -9,6 +9,7 @@
###### 2025/04/12
* `新增` ui.statusBarAppearanceLight/statusBarAppearanceLightBy/navigationBarColor 等方法
* `新增` images.flip 方法, 用于图像翻转 _[`issue #349`](http://issues.autojs6.com/349)_
* `新增` 设置页面增加 "文件扩展名" 设置选项
* `新增` 主题色设置页面增加新布局支持 (分组/定位/搜索/历史记录/调色盘增强等)
* `修复` Android 15 状态栏背景颜色与主题色不一致的问题

View File

@@ -9,6 +9,7 @@
###### 2025/04/12
* `新增` ui.statusBarAppearanceLight/statusBarAppearanceLightBy/navigationBarColor 等方法
* `新增` images.flip 方法, 用于图像翻转 _[`issue #349`](http://issues.autojs6.com/349)_
* `新增` 设置页面增加 "文件扩展名" 设置选项
* `新增` 主题色设置页面增加新布局支持 (分组/定位/搜索/历史记录/调色盘增强等)
* `修复` Android 15 状态栏背景颜色与主题色不一致的问题

View File

@@ -10,17 +10,17 @@ import com.stardust.automator.UiObject
class SearchUpTargetAction(action: Int, filter: FilterAction.Filter) : SearchTargetAction(action, filter) {
private val mAble: Able = Able.ABLE_MAP.get(action)
override fun searchTarget(n: UiObject?): UiObject? {
var node = n
override fun searchTarget(node: UiObject?): UiObject? {
var targetNode = node
var i = 0
while (node != null && !mAble.isAble(node)) {
while (targetNode != null && !mAble.isAble(targetNode)) {
i++
if (i > LOOP_MAX) {
return null
}
node = node.parent()
targetNode = targetNode.parent()
}
return node
return targetNode
}
override fun toString(): String {

View File

@@ -280,6 +280,26 @@ public class Images {
return imageWrapper;
}
@ScriptInterface
public ImageWrapper flip(@NonNull ImageWrapper img, boolean horizontal, boolean vertical) {
Bitmap original = img.getBitmap();
Matrix matrix = new Matrix();
// 根据传入参数设置缩放比例
float sx = horizontal ? -1.0f : 1.0f;
float sy = vertical ? -1.0f : 1.0f;
matrix.preScale(sx, sy);
// 水平方向翻转后, 平移到图像宽度的位置
if (horizontal) matrix.postTranslate(original.getWidth(), 0);
// 垂直方向翻转后, 平移到图像高度的位置
if (vertical) matrix.postTranslate(0, original.getHeight());
Bitmap flipped = Bitmap.createBitmap(original, 0, 0, original.getWidth(), original.getHeight(), matrix, true);
img.shoot();
return ImageWrapper.ofBitmap(flipped);
}
public ImageWrapper clip(@NonNull ImageWrapper img, int x, int y, int w, int h) {
ImageWrapper imageWrapper = ImageWrapper.ofBitmap(Bitmap.createBitmap(img.getBitmap(), x, y, w, h));
img.shoot();

View File

@@ -17,6 +17,9 @@ class Classes {
@JvmField
val PendingIntent = android.app.PendingIntent::class
@JvmField
val ComponentName = android.content.ComponentName::class
@JvmField
val Context = android.content.Context::class

View File

@@ -99,6 +99,7 @@ class Images(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), AsEmitt
::resizeInternal.name,
::scale.name,
::rotate.name,
::flip.name,
::concat.name,
::detectColor.name,
::detectsColor.name,
@@ -598,6 +599,49 @@ class Images(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), AsEmitt
scriptRuntime.images.rotate(image, centerX, centerY, coerceFloatNumber(degree))
}
@JvmStatic
@RhinoRuntimeFunctionInterface
fun flip(scriptRuntime: ScriptRuntime, args: Array<out Any?>): ImageWrapper = ensureArgumentsLengthInRange(args, 1..3) { argList ->
val image = if (argList[0] is String) read(scriptRuntime, arrayOf(argList[0], true)) else argList[0]
require(image is ImageWrapper) { "Argument image for images.flip must be a ImageWrapper" }
val (horizontal, vertical) = when (argList.size) {
1 -> true to false
2 -> parseFlipOrientations(argList[1])
3 -> coerceBoolean(argList[1], false) to coerceBoolean(argList[2], false)
else -> throw WrappedIllegalArgumentException("Arguments length (${args.size}) is unacceptable for images.flip")
}
initOpenCvIfNeeded()
scriptRuntime.images.flip(image, horizontal, vertical)
}
private fun parseFlipOrientations(o: Any?): Pair<Boolean, Boolean> = when {
o.isJsNullish() -> false to false
o is Boolean -> o to false
o is String -> {
val lower = o.lowercase().trim()
val bothPattern = Regex("^(both|all|h\\|v|v\\|h|xy|yx|x\\|y|y\\|x)$")
val hPattern = Regex("^(h|horizontal|x)$")
val vPattern = Regex("^(v|vertical|y)$")
when {
bothPattern.matches(lower) -> true to true
hPattern.matches(lower) -> true to false
vPattern.matches(lower) -> false to true
else -> coerceBoolean(o, false) to false
}
}
o is NativeArray -> when (o.size) {
0 -> false to false
1 -> coerceBoolean(o[0], false) to false
else -> coerceBoolean(o[0], false) to coerceBoolean(o[1], false)
}
o is NativeObject -> {
val h = o.inquire(listOf("x", "h", "horizontal"), ::coerceBoolean, false)
val v = o.inquire(listOf("y", "v", "vertical"), ::coerceBoolean, false)
h to v
}
else -> false to false
}
@JvmStatic
@RhinoRuntimeFunctionInterface
fun concat(scriptRuntime: ScriptRuntime, args: Array<out Any?>): ImageWrapper = ensureArgumentsLengthInRange(args, 2..3) {