Có thể bằng cách nào đó để kết hợp hình ảnh PNG với hình ảnh động APNG bằng cách sử dụng nút jj không?Tham gia hình ảnh PNG lên hình ảnh động APNG
tôi đã tìm thấy PHP chỉ thư viện: link
Có thể bằng cách nào đó để kết hợp hình ảnh PNG với hình ảnh động APNG bằng cách sử dụng nút jj không?Tham gia hình ảnh PNG lên hình ảnh động APNG
tôi đã tìm thấy PHP chỉ thư viện: link
Tôi không chắc chắn về nodejs, nhưng bạn có thể thử APNG-canvas. APNG sử dụng HTML5 (-webkit-canvas), JavaScript (jQuery).
"APNG-canvas là thư viện để chuyển các tệp PNG hoạt ảnh trong trình duyệt bằng hỗ trợ canvas (Google Chrome, Internet Explorer 9, Apple Safari)."
Làm việc demo có tại đây.
Thư viện này không hỗ trợ tạo file APNG. – 1j01
Currently, không giống như vậy. Wikipedia lists the available software và bạn có thể thấy không có hỗ trợ cho ImageMagick có trình bao bọc nút. Tuy nhiên, bạn có thể thấy rằng bạn có thể tải xuống command line tool apngasm và loại bỏ nó, nếu bạn thấy nó đáng giá trong khi có các trình bao bọc dòng lệnh Nút để móc ứng dụng này vào ứng dụng hiện có bằng cách sử dụng child_process
(http://nodejs.org/api/child_process.html).
Không có thư viện cho điều đó, nhưng thực hiện khá đơn giản. Thuật toán cho việc sáp nhập nhiều file PNG vào đơn APNG được mô tả trong Wikipedia:
- Mang tất cả những phần của tệp PNG đầu tiên làm cơ sở xây dựng.
- Chèn đoạn điều khiển hoạt ảnh (acTL) sau đoạn tiêu đề hình ảnh (IHDR).
- Nếu PNG đầu tiên là một phần của hoạt ảnh, hãy chèn đoạn điều khiển khung (fcTL) trước đoạn dữ liệu hình ảnh (IDAT).
- Đối với mỗi khung còn lại, thêm đoạn điều khiển khung (fcTL) và khung dữ liệu khung (fdAT). Sau đó, thêm đoạn cuối hình ảnh (IEND). Nội dung cho các khối dữ liệu khung (fdAT) được lấy từ các khối dữ liệu hình ảnh (IDAT) của các hình ảnh nguồn tương ứng của chúng.
Đây là một thực hiện ví dụ:
const fs = require('fs')
const crc32 = require('crc').crc32
function findChunk(buffer, type) {
let offset = 8
while (offset < buffer.length) {
let chunkLength = buffer.readUInt32BE(offset)
let chunkType = buffer.slice(offset + 4, offset + 8).toString('ascii')
if (chunkType === type) {
return buffer.slice(offset, offset + chunkLength + 12)
}
offset += 4 + 4 + chunkLength + 4
}
throw new Error(`Chunk "${type}" not found`)
}
const images = process.argv.slice(2).map(path => fs.readFileSync(path))
const actl = Buffer.alloc(20)
actl.writeUInt32BE(8, 0) // length of chunk
actl.write('acTL', 4) // type of chunk
actl.writeUInt32BE(images.length, 8) // number of frames
actl.writeUInt32BE(0, 12) // number of times to loop (0 - infinite)
actl.writeUInt32BE(crc32(actl.slice(4, 16)), 16) // crc
const frames = images.map((data, idx) => {
const ihdr = findChunk(data, 'IHDR')
const fctl = Buffer.alloc(38)
fctl.writeUInt32BE(26, 0) // length of chunk
fctl.write('fcTL', 4) // type of chunk
fctl.writeUInt32BE(idx ? idx * 2 - 1 : 0, 8) // sequence number
fctl.writeUInt32BE(ihdr.readUInt32BE(8), 12) // width
fctl.writeUInt32BE(ihdr.readUInt32BE(12), 16) // height
fctl.writeUInt32BE(0, 20) // x offset
fctl.writeUInt32BE(0, 24) // y offset
fctl.writeUInt16BE(1, 28) // frame delay - fraction numerator
fctl.writeUInt16BE(1, 30) // frame delay - fraction denominator
fctl.writeUInt8(0, 32) // dispose mode
fctl.writeUInt8(0, 33) // blend mode
fctl.writeUInt32BE(crc32(fctl.slice(4, 34)), 34) // crc
const idat = findChunk(data, 'IDAT')
// All IDAT chunks except first one are converted to fdAT chunks
let fdat;
if (idx === 0) {
fdat = idat
} else {
const length = idat.length + 4
fdat = Buffer.alloc(length)
fdat.writeUInt32BE(length - 12, 0) // length of chunk
fdat.write('fdAT', 4) // type of chunk
fdat.writeUInt32BE(idx * 2, 8) // sequence number
idat.copy(fdat, 12, 8) // image data
fdat.writeUInt32BE(crc32(4, length - 4), length - 4) // crc
}
return Buffer.concat([ fctl, fdat ])
})
const signature = Buffer.from('\211PNG\r\n\032\n', 'ascii')
const ihdr = findChunk(images[0], 'IHDR')
const iend = Buffer.from('0000000049454e44ae426082', 'hex')
const output = Buffer.concat([ signature, ihdr, actl, ...frames, iend ])
fs.writeFileSync('output.png', output)
UPNG.js có thể phân tích và xây dựng các file APNG - https://github.com/photopea/UPNG.js
Từ readme -
UPNG. js hỗ trợ APNG và giao diện mong đợi "khung".
UPNG.encode (imgs, w, h, cnum, [dels])
imgs: array of frames. A frame is an ArrayBuffer containing the pixel data (RGBA, 8 bits per channel) w, h : width and height of the image cnum: number of colors in the result; 0: all colors (lossless PNG) dels: array of delays for each frame (only when 2 or more frames) returns an ArrayBuffer with binary data of a PNG file
UPNG.js có thể làm một việc rút gọn lossy các tập tin PNG, tương tự như TinyPNG và các công cụ khác. Nó thực hiện lượng tử hóa màu bằng cách sử dụng thuật toán k-means .
Nén tổn hao được phép bởi thông số cnum cuối cùng. Đặt nó thành 0 để nén không mất dữ liệu hoặc ghi số màu được phép vào hình ảnh. Giá trị nhỏ hơn tạo ra các tệp nhỏ hơn.Hoặc chỉ cần sử dụng 0 cho lossless/256 cho lossy.
Tôi nghĩ rằng bạn sẽ tìm thấy những gì bạn cần trên wikipedia dưới phần Hỗ trợ ứng dụng: http://en.wikipedia.org/wiki/APNG#Application_support –