diff --git a/Demo/SanjuuniApi-Demo/demo.mp4 b/Demo/SanjuuniApi-Demo/demo.mp4 new file mode 100644 index 0000000..5b7bace Binary files /dev/null and b/Demo/SanjuuniApi-Demo/demo.mp4 differ diff --git a/Demo/SanjuuniApi-Demo/demo2.lua b/Demo/SanjuuniApi-Demo/demo2.lua index dc56744..350073b 100644 --- a/Demo/SanjuuniApi-Demo/demo2.lua +++ b/Demo/SanjuuniApi-Demo/demo2.lua @@ -1,67 +1,187 @@ --- API 地址 / API Endpoint +-- sanjuuni_converter.lua +-- 使用Sanjuuni API的图像转换工具 +-- Usage: sanjuuni_converter --url --format --out [options] + local API_URL = "http://newgmapi.liulikeji.cn/api/sanjuuni" --- 输入图片URL / Input image URL -local INPUT_URL = "https://git.liulikeji.cn/xingluo/CCTweaked-Demo/raw/branch/main/Demo/SanjuuniApi-Demo/demo.gif" +-- 显示帮助信息 +local function showHelp() + print("Sanjuuni Image Converter - Usage:") + print("sanjuuni_converter --url --format --out [options]") + print() + print("Required arguments:") + print(" --url Input image URL") + print(" --format Output format (bimg, gif, etc.)") + print(" --out Output file path") + print() + print("Options:") + print(" --args Conversion parameters (default: \"-8\")") + print(" --monitor Use specified monitor for size reference") + print(" --scale Set display scale before getting monitor size") + print(" --help Show this help message") + print() + print("Example:") + print("sanjuuni_converter --url https://example.com/image.jpg --format bimg --out output.bimg") + print("sanjuuni_converter --url https://example.com/image.jpg --format gif --out anim.gif --monitor top --scale 0.5") +end - -local function Get_image_url(INPUT_URL,API_URL,args,output_format) - -- ===== 1. 发送HTTP请求 / Send HTTP request ===== +-- 获取图像下载URL +local function getImageUrl(inputUrl, args, outputFormat) + -- 准备请求数据 local requestData = { - input_url = INPUT_URL, + input_url = inputUrl, args = args, - output_format = output_format + output_format = outputFormat } + print("Sending request to Sanjuuni API...") local response, err = http.post( + API_URL, textutils.serializeJSON(requestData), { ["Content-Type"] = "application/json" } ) - -- ===== 2. 读取数据 / Send HTTP request ===== - if not response then error("HTTP Request Failure: "..(err or "Unknown error")) - else - -- 读取响应 / Read response - local responseData = textutils.unserializeJSON(response.readAll()) - response.close() + if not response then + error("HTTP request failed: "..(err or "unknown error")) + end - --返回下载链接 / Return download URL - if responseData.status ~= "success" then error("Conversion failed:"..(responseData.error or "Unknown error")) + -- 解析响应数据 + local responseData = textutils.unserializeJSON(response.readAll()) + response.close() + + if responseData.status ~= "success" then + error("Conversion failed: "..(responseData.error or "unknown error")) + end + + print("Conversion successful!") + return responseData.download_url +end + +-- 下载文件到本地 +local function downloadFile(url, outputPath) + print("Downloading converted file...") + local response = http.get(url) + if not response then + error("Failed to download file from: "..url) + end + + local file = fs.open(outputPath, "wb") + if not file then + error("Cannot open output file: "..outputPath) + end + + file.write(response.readAll()) + file.close() + response.close() + + print("File saved to: "..outputPath) +end + +-- 解析命令行参数 +local function parseArguments(args) + local options = { + args = {} -- 默认参数 + } + local required = {"url", "format", "out"} + local seen = {} + + local i = 1 + while i <= #args do + local arg = args[i] + if arg == "--url" then + i = i + 1 + options.url = args[i] + seen.url = true + elseif arg == "--format" then + i = i + 1 + options.format = args[i] + seen.format = true + elseif arg == "--out" then + i = i + 1 + options.out = args[i] + seen.out = true + elseif arg == "--args" then + i = i + 1 + options.args = {args[i]} -- 简单参数处理 + elseif arg == "--monitor" then + i = i + 1 + options.monitor = args[i] + elseif arg == "--scale" then + i = i + 1 + options.scale = tonumber(args[i]) + elseif arg == "--help" then + showHelp() + return nil else - return responseData.download_url + error("Unknown option: "..arg) + end + i = i + 1 + end + + -- 检查必需参数 + for _, req in ipairs(required) do + if not seen[req] then + error("Missing required argument: --"..req) end end + + return options end +-- 主函数 +local function main(...) + local args = {...} + + if #args == 0 then + showHelp() + return + end --- 图片宽度 / Image width -local width, height = term.getSize() -- 获取终端尺寸(width=宽度,height=高度) -local width = width * 2 -- 宽度×2 -local height = height * 3 -- 高度×3 + -- 解析参数 + local ok, options = pcall(parseArguments, args) + if not ok then + printError(options) -- options contains error message + showHelp() + return + end --- 转换参数 / Conversion parameters -args = { "-8","--width="..width,"--height="..height } -output_format = "bimg" + if not options then return end -- 用户请求帮助 --- 调用API / Call API -local download_url = Get_image_url(INPUT_URL,API_URL,args,output_format) + -- 获取终端/显示器尺寸 + local width, height + if options.monitor then + local monitor = peripheral.wrap(options.monitor) + if not monitor then + error("Invalid monitor: "..options.monitor) + end + + if options.scale then + monitor.setTextScale(options.scale) + end + + width, height = monitor.getSize() + else + width, height = term.getSize() + end + -- 计算最终尺寸 + width = width * 2 + height = height * 3 --- 下载图像文件 / Download image file -print("\nConversion successful! Download URL:") -print(download_url) + -- 准备转换参数 + local conversionArgs = options.args + table.insert(conversionArgs, "--width="..width) + table.insert(conversionArgs, "--height="..height) -luafile = http.get(download_url) -if luafile then - print("\nLua file downloaded successfully.") + -- 调用API转换图像 + local downloadUrl = getImageUrl(options.url, conversionArgs, options.format) - -- 保存bimg文件 / Save bimg file - f = fs.open("demo.bimg", "w") - f.write(luafile.readAll()) - f.close() - print("\nLua file saved as demo.bimg.") + -- 下载转换后的文件 + downloadFile(downloadUrl, options.out) -else - print("\nFailed to download Lua file.") + print("Image conversion completed successfully!") end + +-- 运行程序 +main(...) \ No newline at end of file diff --git a/Demo/SanjuuniApi-Demo/lib/32vid-player-mini.lua b/Demo/SanjuuniApi-Demo/lib/32vid-player-mini.lua deleted file mode 100644 index ef6e9c7..0000000 --- a/Demo/SanjuuniApi-Demo/lib/32vid-player-mini.lua +++ /dev/null @@ -1,261 +0,0 @@ --- 32vid-player-mini from sanjuuni --- Licensed under the MIT license - -local bit32_band, bit32_lshift, bit32_rshift, math_frexp = bit32.band, bit32.lshift, bit32.rshift, math.frexp -local function log2(n) local _, r = math_frexp(n) return r-1 end -local dfpwm = require "cc.audio.dfpwm" - -local speaker = peripheral.find "speaker" -local file -local path = ... -if path:match "^https?://" then - file = assert(http.get(path, nil, true)) -else - file = assert(fs.open(shell.resolve(path), "rb")) -end - -if file.read(4) ~= "32VD" then file.close() error("Not a 32Vid file") end -local width, height, fps, nstreams, flags = ("= 16 then - local l = 2^(t.s - 15) - for n = 0, l-1 do retval[i+n] = last end - i = i + l - else retval[i], last, i = t.s, t.s, i + 1 end - X = t.X + readbits(t.n) - end - --print(X) - return retval - end -else - error("Unimplemented!") -end - -local blitColors = {[0] = "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"} -local start = os.epoch "utc" -local lastyield = start -local vframe = 0 -local subs = {} -term.clear() -for _ = 1, nframes do - local size, ftype = (" 3000 then sleep(0) lastyield = os.epoch "utc" end - local dcstart = os.epoch "utc" - --print("init screen", vframe, file.seek()) - init(false) - --print("read screen", vframe, file.seek()) - local screen = read(width * height) - --print("init colors", vframe, file.seek()) - init(true) - --print("read bg colors", vframe) - local bg = read(width * height) - --print("read fg colors", vframe) - local fg = read(width * height) - local dctime = os.epoch "utc" - dcstart - while os.epoch "utc" < start + vframe * 1000 / fps do end - local texta, fga, bga = {}, {}, {} - for y = 0, height - 1 do - local text, fgs, bgs = "", "", "" - for x = 1, width do - text = text .. string.char(128 + screen[y*width+x]) - fgs = fgs .. blitColors[fg[y*width+x]] - bgs = bgs .. blitColors[bg[y*width+x]] - end - texta[y+1], fga[y+1], bga[y+1] = text, fgs, bgs - end - for i = 0, 15 do term.setPaletteColor(2^i, file.read() / 255, file.read() / 255, file.read() / 255) end - for y = 1, height do - term.setCursorPos(1, y) - term.blit(texta[y], fga[y], bga[y]) - end - local delete = {} - for i, v in ipairs(subs) do - if vframe <= v.frame + v.length then - term.setCursorPos(v.x, v.y) - term.setBackgroundColor(v.bgColor) - term.setTextColor(v.fgColor) - term.write(v.text) - else delete[#delete+1] = i end - end - for i, v in ipairs(delete) do table.remove(subs, v - i + 1) end - --term.setCursorPos(1, height + 1) - --term.clearLine() - --print("Frame decode time:", dctime, "ms") - vframe = vframe + 1 - elseif ftype == 1 then - local audio = file.read(size) - if speaker then - if bit32_band(flags, 12) == 0 then - local chunk = {audio:byte(1, -1)} - for i = 1, #chunk do chunk[i] = chunk[i] - 128 end - speaker.playAudio(chunk) - else - speaker.playAudio(dfpwm.decode(audio)) - end - end - elseif ftype == 8 then - local data = file.read(size) - local sub = {} - sub.frame, sub.length, sub.x, sub.y, sub.color, sub.flags, sub.text = ("= 0x40 and ftype < 0x80 then - if ftype == 64 then vframe = vframe + 1 end - local mx, my = bit32_band(bit32_rshift(ftype, 3), 7) + 1, bit32_band(ftype, 7) + 1 - --print("(" .. mx .. ", " .. my .. ")") - local term = monitors[my][mx] - if os.epoch "utc" - lastyield > 3000 then sleep(0) lastyield = os.epoch "utc" end - local width, height = ("