Browse Source

Face

master
marcoschmickler 5 days ago
parent
commit
c45a9d034a
  1. 213
      kplayer/detail/EditItemView.swift

213
kplayer/detail/EditItemView.swift

@ -36,8 +36,7 @@ struct TagEditor: View {
Button(action: {
if item.tags.contains(tag) {
item.tags.removeAll(where: { toRemove in toRemove == tag })
}
else {
} else {
item.tags.append(tag)
}
if let c = self.completionHandler {
@ -54,7 +53,8 @@ struct TagEditor: View {
Color.gray.opacity(0.4)
)
)
}).buttonStyle(BorderlessButtonStyle())
})
.buttonStyle(BorderlessButtonStyle())
}
}
}
@ -69,6 +69,33 @@ struct EditItemView: View {
@State
var snap = true
@State
var processedImageURL: String?
@State
var isProcessing = false
@State
var showProcessedImage = false
@State
var loadedImage: UIImage?
@State
var imageLoadError: String?
@State
var imageScale: CGFloat = 1.0
@State
var imageOffset: CGSize = .zero
@State
var lastScale: CGFloat = 1.0
@State
var lastOffset: CGSize = .zero
var len: Double
var delegate: EditItemDelegate
@ -98,7 +125,8 @@ struct EditItemView: View {
}), in: 0...len) {
Button(action: delegate.setStart, label: {
Text("Start")
}).buttonStyle(BorderlessButtonStyle());
})
.buttonStyle(BorderlessButtonStyle());
}
Stepper(value: Binding<Double>(
get: { item.length },
@ -111,20 +139,23 @@ struct EditItemView: View {
}
Button(action: delegate.setEnd, label: {
Text("End")
}).buttonStyle(BorderlessButtonStyle());
})
.buttonStyle(BorderlessButtonStyle());
}
Text("Zoom \(item.scale, specifier: "%.1f") X \(item.offset.x, specifier: "%.1f") Y \(item.offset.y, specifier: "%.1f") ")
HStack {
Button(action: delegate.captureZoom, label: {
Text("Zoom")
}).padding(5).buttonStyle(BorderlessButtonStyle());
})
.padding(5).buttonStyle(BorderlessButtonStyle());
Button(action: {
item.scale = 1.0
item.offset = CGPoint(x: 0, y: 0)
item.objectWillChange.send()
}, label: {
Text("Reset")
}).padding(5).buttonStyle(BorderlessButtonStyle());
})
.padding(5).buttonStyle(BorderlessButtonStyle());
Stepper(value: $item.rating, in: -1...5) {
Text("*\(item.rating)").frame(width: 25)
}
@ -132,11 +163,13 @@ struct EditItemView: View {
delegate.okEdit()
}, label: {
Text("ok")
}).padding(5).buttonStyle(BorderlessButtonStyle());Button(action: {
})
.padding(5).buttonStyle(BorderlessButtonStyle()); Button(action: {
delegate.cancelEdit()
}, label: {
Text("cancel")
}).padding(5).buttonStyle(BorderlessButtonStyle());
})
.padding(5).buttonStyle(BorderlessButtonStyle());
}
VStack {
KToggleButton(text: "snap", binding: $snap)
@ -150,10 +183,13 @@ struct EditItemView: View {
Button(action: { faceSelectedItem("nina"); }, label: { Text("nina") }).buttonStyle(BorderlessButtonStyle())
Button(action: { faceSelectedItem("amruta"); }, label: { Text("amruta") }).buttonStyle(BorderlessButtonStyle())
}
TagEditor(item: item)
}.background(Color.clear)
}.background(Color.clear)
}
.background(Color.clear)
}
.background(Color.clear)
}
.onAppear {
UITableView.appearance().backgroundColor = .clear
@ -162,9 +198,136 @@ struct EditItemView: View {
UITableView.appearance().backgroundColor = .systemBackground
}
.frame(height: 800, alignment: .top)
.sheet(isPresented: $showProcessedImage) {
NavigationView {
VStack {
if let image = loadedImage {
GeometryReader { geometry in
Image(uiImage: image)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: geometry.size.width, height: geometry.size.height)
.scaleEffect(imageScale)
.offset(imageOffset)
.gesture(
SimultaneousGesture(
MagnificationGesture()
.onChanged { value in
let delta = value / lastScale
lastScale = value
let newScale = imageScale * delta
imageScale = min(max(newScale, 1.0), 5.0)
}
.onEnded { value in
lastScale = 1.0
},
DragGesture(minimumDistance: 0)
.onChanged { value in
imageOffset = CGSize(
width: lastOffset.width + value.translation.width,
height: lastOffset.height + value.translation.height
)
}
.onEnded { value in
lastOffset = imageOffset
}
)
)
.onTapGesture(count: 2) {
// Double tap to reset zoom
withAnimation(.spring(response: 0.3, dampingFraction: 0.7)) {
imageScale = 1.0
lastScale = 1.0
imageOffset = .zero
lastOffset = .zero
}
}
}
} else if let error = imageLoadError {
VStack(spacing: 20) {
Image(systemName: "exclamationmark.triangle")
.font(.system(size: 60))
.foregroundColor(.orange)
Text("Failed to load image")
.font(.headline)
Text(error)
.font(.caption)
.foregroundColor(.secondary)
if let imageURL = processedImageURL {
Text("URL: \(imageURL)")
.font(.caption2)
.foregroundColor(.secondary)
}
}
.padding()
} else {
ProgressView("Loading image...")
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
.navigationTitle("Processed Image")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
if loadedImage != nil && imageScale != 1.0 {
Button("Reset") {
withAnimation(.spring(response: 0.3, dampingFraction: 0.7)) {
imageScale = 1.0
lastScale = 1.0
imageOffset = .zero
lastOffset = .zero
}
}
}
}
ToolbarItem(placement: .navigationBarTrailing) {
Button("Done") {
showProcessedImage = false
loadedImage = nil
imageLoadError = nil
// Reset zoom state
imageScale = 1.0
lastScale = 1.0
imageOffset = .zero
lastOffset = .zero
}
}
}
.task {
if let imageURL = processedImageURL {
await loadImageFromURL(imageURL)
}
}
}
}
//Spacer()
}
func loadImageFromURL(_ urlString: String) async {
guard let url = URL(string: urlString) else {
imageLoadError = "Invalid URL"
return
}
do {
let (data, _) = try await URLSession.shared.data(from: url)
if let image = UIImage(data: data) {
await MainActor.run {
loadedImage = image
imageLoadError = nil
}
} else {
await MainActor.run {
imageLoadError = "Failed to create image from data"
}
}
} catch {
await MainActor.run {
imageLoadError = "Failed to load image: \(error.localizedDescription)"
}
}
}
func faceSelectedItem(_ name: String) {
let path = item.fullPath.replacing("/srv/samba/ren", with: "z:")
let outpath1 = path.replacing("/", with: "")
@ -177,6 +340,9 @@ struct EditItemView: View {
Task {
isProcessing = true
processedImageURL = nil
if (snap) {
let imagePath = item.imageUrlAbsolute.replacing("http://linkstation:8089/ren", with: "z:").replacing("_thumb", with: "")
print(imagePath)
@ -184,14 +350,33 @@ struct EditItemView: View {
let outimagepath = "z:/cut/snapshots/" + name + "/" + imagePath.substringStartingFrom(2).replacing("/", with: "")
try await FaceManager.sharedInstance.processImage(inputImagePath: imagePath, sourceFacePath: "benchmark/"+name+".jpg", outputPath: outimagepath)
do {
let response = try await FaceManager.sharedInstance.processImage(inputImagePath: imagePath, sourceFacePath: "benchmark/" + name + ".jpg", outputPath: outimagepath)
//if response.success, let outputPath = response.outputPath {
// Convert Windows path back to HTTP URL
let httpURL = outimagepath.replacing("z:", with: "http://linkstation:8089/ren").replacing("\\", with: "/")
processedImageURL = httpURL
print("Processed image URL: \(httpURL)")
// Show the sheet with the processed image
showProcessedImage = true
isProcessing = false
} catch {
print("Error processing image: \(error)")
isProcessing = false
}
else {
} else {
do {
try await FaceManager.sharedInstance.processVideo(inputVideoPath: path, sourceFacePath: "benchmark/" + name + ".jpg", outputPath: outpath)
//try! await FaceManager.sharedInstance.processImage(inputImagePath: "input", sourceFacePath: "benchmark/Renate.jpg")
delegate.cancelEdit()
isProcessing = false
} catch {
print("Error processing video: \(error)")
isProcessing = false
}
}
}

Loading…
Cancel
Save