Skip to content

Commit

Permalink
导出长图
Browse files Browse the repository at this point in the history
  • Loading branch information
caol64 committed Oct 16, 2024
1 parent beb694f commit bfbea4b
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 2 deletions.
19 changes: 19 additions & 0 deletions WenYan/Commons.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

import Foundation
import WebKit
import UniformTypeIdentifiers
import SwiftUI

struct WebkitStatus {
static let loadHandler = "loadHandler"
Expand Down Expand Up @@ -226,3 +228,20 @@ enum Platform: String, CaseIterable, Identifiable {
}
}
}

struct DataFile: FileDocument {
static var readableContentTypes: [UTType] { [.jpeg] }
var data: Data

init(data: Data) {
self.data = data
}

init(configuration: ReadConfiguration) throws {
data = configuration.file.regularFileContents ?? Data()
}

func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
return FileWrapper(regularFileWithContents: data)
}
}
29 changes: 28 additions & 1 deletion WenYan/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,34 @@ struct ContentView: View {
}
.frame(height: 24)
}
Button(action: {
htmlViewModel.showFileExporter = true
htmlViewModel.exportLongImage()
}) {
HStack {
Image(systemName: "photo")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 16, height: 16)
Text("长图")
.font(.system(size: 14))
}
.frame(height: 24)
}
.fileExporter(
isPresented: $htmlViewModel.showFileExporter,
document: htmlViewModel.longImageData,
contentType: .jpeg,
defaultFilename: "out"
) { result in
switch result {
case .success(let url):
print("File saved to \(url)")
case .failure(let error):
appState.appError = AppError.bizError(description: error.localizedDescription)
}
htmlViewModel.longImageData = nil
}
Button(action: {
htmlViewModel.onCopy()
}) {
Expand All @@ -86,7 +114,6 @@ struct ContentView: View {
}
.frame(height: 24)
}

}
.padding(.trailing, 32)
.padding(.top, 16)
Expand Down
58 changes: 58 additions & 0 deletions WenYan/HtmlView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ class HtmlViewModel: NSObject, WKNavigationDelegate, WKScriptMessageHandler {
var isCopied = false
var isFootnotes = false
var gzhTheme: ThemeStyle = Platform.gzh.themes[0]
var showFileExporter: Bool = false
var longImageData: DataFile?

init(appState: AppState) {
self.appState = appState
Expand Down Expand Up @@ -136,6 +138,10 @@ extension HtmlViewModel {
callJavascript(javascriptString: "getContentForMedium();", callback: block)
}

func getScrollFrame(_ block: JavascriptCallback?) {
callJavascript(javascriptString: "getScrollFrame();", callback: block)
}

func setPreviewMode() {
callJavascript(javascriptString: "setPreviewMode(\"\(previewMode.rawValue)\");")
}
Expand Down Expand Up @@ -262,5 +268,57 @@ extension HtmlViewModel {
UserDefaults.standard.set(gzhTheme.rawValue, forKey: "gzhTheme")
}
}

func exportLongImage() {
if !showFileExporter {
return
}
guard let webView = self.webView else {
return
}
getScrollFrame { result in
do {
print(try result.get())
guard let body = try result.get() as? [String: CGFloat],
let x = body["x"],
let y = body["y"],
let width = body["width"],
let height = body["height"]
else {
return
}
print(body)
// let fullHeight = try result.get() as! CGFloat
let originalFrame = webView.frame
let newFrame = NSRect(x: x, y: y, width: width, height: height)
// guard let bitmapRep = webView.bitmapImageRepForCachingDisplay(in: newFrame) else {
// return
// }
// webView.cacheDisplay(in: webView.bounds, to: bitmapRep)
// let jpegData = bitmapRep.representation(using: .jpeg, properties: [.compressionFactor: 0.9]) // 设置压缩系数为 0.9
// if let data = jpegData {
// self.longImageData = DataFile(data: data)
// }
webView.frame = newFrame
let configuration = WKSnapshotConfiguration()
webView.takeSnapshot(with: configuration) { image, error in
if let image = image {
guard let tiffData = image.tiffRepresentation,
let bitmapRep = NSBitmapImageRep(data: tiffData) else {
return
}
let jpegData = bitmapRep.representation(using: .jpeg, properties: [.compressionFactor: 0.9]) // 设置压缩系数为 0.9
if let data = jpegData {
self.longImageData = DataFile(data: data)
}
}
}

webView.frame = originalFrame
} catch {
self.appState.appError = AppError.bizError(description: error.localizedDescription)
}
}
}

}
9 changes: 8 additions & 1 deletion WenYan/Resources.bundle/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,14 @@ marked.use({
renderer: renderer
});
// ------- marked.js默认配置完毕 -------

function getScrollFrame() {
const height = document.body.scrollHeight;
const width = document.getElementById("wenyan").offsetWidth;
const fullWidth = document.body.scrollWidth;
const x = (fullWidth - width) / 2;
const y = 0;
return { x: x, y: y, width: width, height, height }
}
function setStylesheet(id, href) {
const style = document.createElement("link");
style.setAttribute("id", id);
Expand Down
2 changes: 2 additions & 0 deletions WenYan/WenYan.entitlements
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
</dict>
Expand Down

0 comments on commit bfbea4b

Please sign in to comment.