解决合并冲突,保留本地功能
This commit is contained in:
73
.gitignore
vendored
73
.gitignore
vendored
@@ -1,71 +1,6 @@
|
|||||||
# Built application files
|
# Ignore Windows reserved files
|
||||||
*.apk
|
NUL
|
||||||
*.ap_
|
|
||||||
*.aab
|
|
||||||
|
|
||||||
# Files for the ART/Dalvik VM
|
# Android/ Gradle build outputs (optional for CI, can be kept locally if desired)
|
||||||
*.dex
|
**/build/
|
||||||
|
|
||||||
# Java class files
|
|
||||||
*.class
|
|
||||||
|
|
||||||
# Generated files
|
|
||||||
bin/
|
|
||||||
gen/
|
|
||||||
out/
|
|
||||||
|
|
||||||
# Gradle files
|
|
||||||
.gradle/
|
.gradle/
|
||||||
build/
|
|
||||||
|
|
||||||
# Local configuration file (sdk path, etc)
|
|
||||||
local.properties
|
|
||||||
|
|
||||||
# Proguard folder generated by Eclipse
|
|
||||||
proguard/
|
|
||||||
|
|
||||||
# Log Files
|
|
||||||
*.log
|
|
||||||
|
|
||||||
# Android Studio Navigation editor temp files
|
|
||||||
.navigation/
|
|
||||||
|
|
||||||
# Android Studio captures folder
|
|
||||||
captures/
|
|
||||||
|
|
||||||
# IntelliJ
|
|
||||||
*.iml
|
|
||||||
.idea/
|
|
||||||
|
|
||||||
# Keystore files
|
|
||||||
*.jks
|
|
||||||
*.keystore
|
|
||||||
|
|
||||||
# External native build folder generated in Android Studio 2.2 and later
|
|
||||||
.externalNativeBuild
|
|
||||||
.cxx/
|
|
||||||
|
|
||||||
# Google Services (API key)
|
|
||||||
google-services.json
|
|
||||||
|
|
||||||
# Freeline
|
|
||||||
freeline.py
|
|
||||||
freeline/
|
|
||||||
freeline_project_description.json
|
|
||||||
|
|
||||||
# fastjson
|
|
||||||
fastjson/
|
|
||||||
|
|
||||||
# Test folder
|
|
||||||
test/
|
|
||||||
tests/
|
|
||||||
|
|
||||||
# Python
|
|
||||||
__pycache__/
|
|
||||||
*.py[cod]
|
|
||||||
*$py.class
|
|
||||||
|
|
||||||
# Airtest
|
|
||||||
*.log
|
|
||||||
*.png
|
|
||||||
report/
|
|
||||||
|
|||||||
59
app/src/main/java/com/inspection/camera/util/PuzzleMerge.kt
Normal file
59
app/src/main/java/com/inspection/camera/util/PuzzleMerge.kt
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
package com.inspection.camera.util
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.graphics.BitmapFactory
|
||||||
|
import android.graphics.Canvas
|
||||||
|
import android.graphics.Paint
|
||||||
|
import android.graphics.Rect
|
||||||
|
import android.net.Uri
|
||||||
|
|
||||||
|
object PuzzleMerge {
|
||||||
|
// Merge up to 4 images into a single 2x2 bitmap
|
||||||
|
fun mergeToBitmap(context: Context, imageUris: List<Uri>, targetSize: Int = 1000): Bitmap? {
|
||||||
|
if (imageUris.isEmpty()) return null
|
||||||
|
val size = targetSize
|
||||||
|
val half = size / 2
|
||||||
|
val merged = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888)
|
||||||
|
val canvas = Canvas(merged)
|
||||||
|
val paint = Paint(Paint.ANTI_ALIAS_FLAG)
|
||||||
|
|
||||||
|
val targets = arrayOf(
|
||||||
|
Rect(0, 0, half, half), // TL
|
||||||
|
Rect(half, 0, size, half), // TR
|
||||||
|
Rect(0, half, half, size), // BL
|
||||||
|
Rect(half, half, size, size) // BR
|
||||||
|
)
|
||||||
|
|
||||||
|
val toUse = imageUris.take(4)
|
||||||
|
for (i in toUse.indices) {
|
||||||
|
val bmp = loadBitmap(context, toUse[i], half, half)
|
||||||
|
if (bmp != null) {
|
||||||
|
val scaled = Bitmap.createScaledBitmap(bmp, half, half, true)
|
||||||
|
canvas.drawBitmap(scaled, null, targets[i], paint)
|
||||||
|
bmp.recycle()
|
||||||
|
scaled.recycle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optional: fill empty cells with placeholder color if needed
|
||||||
|
return merged
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load bitmap from URI with sampling to fit within maxW x maxH
|
||||||
|
private fun loadBitmap(context: Context, uri: Uri, maxW: Int, maxH: Int): Bitmap? {
|
||||||
|
return try {
|
||||||
|
val opts = BitmapFactory.Options().apply { inJustDecodeBounds = true }
|
||||||
|
context.contentResolver.openInputStream(uri).use { ins ->
|
||||||
|
BitmapFactory.decodeStream(ins, null, opts)
|
||||||
|
}
|
||||||
|
val inSample = maxOf(1, max(opts.outWidth / maxW, opts.outHeight / maxH))
|
||||||
|
val opts2 = BitmapFactory.Options().apply { inSampleSize = inSample }
|
||||||
|
context.contentResolver.openInputStream(uri).use { ins ->
|
||||||
|
BitmapFactory.decodeStream(ins, null, opts2)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
test/airtest/test_puzzle_merge.py
Normal file
20
test/airtest/test_puzzle_merge.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
AirTest Script: Puzzle Merge - 2x2 large image composition
|
||||||
|
"""
|
||||||
|
|
||||||
|
from airtest.core.api import *
|
||||||
|
auto_setup(__file__)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
start_app("com.inspection.camera")
|
||||||
|
sleep(2)
|
||||||
|
width, height = device().get_current_resolution()
|
||||||
|
# 进入拼图页入口(假设在屏幕右侧)
|
||||||
|
touch((width * 2 / 3, height - 150))
|
||||||
|
sleep(2)
|
||||||
|
snapshot("puzzle_merge_page.png")
|
||||||
|
print("Saved puzzle_merge_page.png")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user