Greasy Fork is available in English.
打开某一话后点击标题右侧按钮生成长图(仅为用于熟人间分享),需要与网络请求修改类浏览器扩展配合
当前为
// ==UserScript==
// @name 动漫之家漫画页转长图
// @namespace https://unlucky.ninja/
// @version 2024.06.18.2
// @description 打开某一话后点击标题右侧按钮生成长图(仅为用于熟人间分享),需要与网络请求修改类浏览器扩展配合
// @author UnluckyNinja
// @license MIT
// @match https://manhua.idmzj.com/*
// @match https://manhua.dmzj.com/*
// @require https://code.jquery.com/jquery-3.7.1.slim.min.js
// @require https://update.greasyfork.icu/scripts/498113/1395364/waitForKeyElements_mirror.js
// @icon https://www.google.com/s2/favicons?sz=64&domain=idmzj.com
// @grant none
// ==/UserScript==
(function() {
'use strict';
// consts
const CANVAS_WIDTH = 800
const JPG_QUALITY = 0.5
// return tarB in tarA/tarB=srcA/srcB
function toRatioValue(srcA, srcB, tarA){
return tarA/srcA * srcB
}
function getTotalHeight(images, width = 800){
let totalH = 0
for (let image of images){
const w = image.naturalWidth
const h = image.naturalHeight
totalH += Math.ceil(toRatioValue(w, h, width))
}
return totalH
}
async function genLongImageBlob(){
const images = [...document.querySelectorAll(".comic_wraCon img").values()]
const canvas = document.createElement('canvas')
const totalHeight = getTotalHeight(images, CANVAS_WIDTH)
let targetWidth = CANVAS_WIDTH
if (totalHeight > 32767) {
let optimalWidth = Math.floor(32767 / totalHeight * CANVAS_WIDTH)
const conti = confirm(`高度超出生成上限: ${totalHeight} / 32767, 若继续生成,则图片宽度将只有:${optimalWidth.toFixed(0)}px,是否继续生成?`)
if (!conti) throw new Error('高度过大无法绘制')
targetWidth = optimalWidth
}
canvas.width = targetWidth
canvas.height = getTotalHeight(images, targetWidth)
const context = canvas.getContext('2d')
let curH = 0
const promises = images.map(it=>it.decode())
await Promise.all(promises)
for (let image of images){
const w = image.naturalWidth
const h = image.naturalHeight
const newH = Math.ceil(toRatioValue(w, h, targetWidth))
console.log(canvas.width)
console.log(canvas.height)
context.drawImage(image, 0, curH, targetWidth, newH)
curH += newH
}
return new Promise((resolve)=>{
canvas.toBlob((blob)=>{
resolve(blob)
}, 'image/jpeg', JPG_QUALITY)
})
}
let downloadButton
let previewButton
async function openImage(){
previewButton.innerText = '生成中...'
previewButton.disabled = true
try {
const blob = await genLongImageBlob()
const url = URL.createObjectURL(blob)
window.open(url, '_blank')
setTimeout(()=>{
URL.revokeObjectURL(url)
}, 10000)
} finally {
previewButton.innerText = '预览长图'
previewButton.disabled = false
}
}
async function downloadImage(){
downloadButton.innerText = '生成中...'
downloadButton.disabled = true
try {
const blob = await genLongImageBlob()
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
const name = document.querySelector('.comic_wraCon h1').textContent
const chapter = document.querySelector('.comic_wraCon h1 ~ span').textContent
a.download = `${name}_${chapter}.jpg`
a.click()
setTimeout(()=>{
URL.revokeObjectURL(url)
}, 0)
} finally {
downloadButton.innerText = '下载长图'
downloadButton.disabled = false
}
}
function addButton(node){
const wrapper = document.createElement('span')
wrapper.style.position = 'relative'
const div = document.createElement('div')
div.style.display = 'flex'
div.style.position = 'absolute'
div.style.width = 'max-content'
div.style.height = '100%'
div.style.left = '100%'
div.style.top = '0'
previewButton = document.createElement('button')
previewButton.innerText = '预览长图'
previewButton.style.margin = '0 0.5rem'
previewButton.addEventListener('click', openImage)
div.append(previewButton)
downloadButton = document.createElement('button')
downloadButton.innerText = '下载长图'
//downloadButton.style.margin = '0 0.5rem'
downloadButton.addEventListener('click', downloadImage)
div.append(downloadButton)
wrapper.append(div)
node[0].parentElement.append(wrapper)
}
waitForKeyElements('.comic_wraCon img', (images)=>{
if (!window.location.href.match(/https?:\/\/manhua.i?dmzj.com\/.*\/.*.shtml.*/)) return
images[0].crossOrigin = 'anonymous'
})
waitForKeyElements('.comic_wraCon h1', (nodes)=>{
if (!window.location.href.match(/https?:\/\/manhua.i?dmzj.com\/.*\/.*.shtml.*/)) return
addButton(nodes)
})
})();