Я пытаюсь создать APNG (анимированный PNG), используя Java, но, к сожалению, все мои попытки до сих пор были неудачными. После некоторого поиска я наткнулся на фрагмент кода, который, казалось, предложил решение. Тем не менее, я все еще сталкиваюсь с проблемами и буду признателен за любым руководством или помощи от сообщества. < /P>
Вот код Java, с которым я работаю: < /p>
public static void createAPNGAnimation(ArrayList images, int delayMs, boolean infinite, FileOutputStream output) throws IOException {
// APNG signature (same as PNG)
byte[] pngSignature = new byte[]{(byte) 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A};
output.write(pngSignature);
// Write IHDR chunk (Image Header)
byte[] ihdr = createIHDRChunk(images.get(0));
output.write(ihdr);
// Write acTL chunk (Animation Control)
byte[] acTL = createACTLChunk(images.size(), infinite ? 0 : 1);
output.write(acTL);
// Write frames
for (int i = 0; i < images.size(); i++) {
BufferedImage image = images.get(i);
// Write fcTL chunk (Frame Control)
byte[] fcTL = createFCTLChunk(i, delayMs, image.getWidth(), image.getHeight());
output.write(fcTL);
// Write IDAT or fdAT chunk (Image Data)
byte[] imageData = createIDATChunk(image);
if (i == 0) {
output.write(imageData); // First frame uses IDAT
} else {
byte[] fdAT = createFDATChunk(i, imageData);
output.write(fdAT); // Subsequent frames use fdAT
}
}
// Write IEND chunk (Image End)
byte[] iend = createIENDChunk();
output.write(iend);
System.out.println("APNG animation created successfully!");
}
private static byte[] createIHDRChunk(BufferedImage image) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(intToBytes(13)); // IHDR data length
baos.write("IHDR".getBytes()); // Chunk type
baos.write(intToBytes(image.getWidth())); // Width
baos.write(intToBytes(image.getHeight())); // Height
baos.write(8); // Bit depth
baos.write(6); // Color type (RGBA)
baos.write(0); // Compression method
baos.write(0); // Filter method
baos.write(0); // Interlace method
byte[] chunkData = baos.toByteArray();
baos.write(intToBytes(crc32(chunkData, 4, chunkData.length - 4))); // CRC
return baos.toByteArray();
}
private static byte[] createACTLChunk(int numFrames, int numPlays) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(intToBytes(8)); // acTL data length
baos.write("acTL".getBytes()); // Chunk type
baos.write(intToBytes(numFrames)); // Number of frames
baos.write(intToBytes(numPlays)); // Number of plays (0 = infinite)
byte[] chunkData = baos.toByteArray();
baos.write(intToBytes(crc32(chunkData, 4, chunkData.length - 4))); // CRC
return baos.toByteArray();
}
private static byte[] createFCTLChunk(int sequenceNumber, int delayMs, int width, int height) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(intToBytes(26)); // fcTL data length
baos.write("fcTL".getBytes()); // Chunk type
baos.write(intToBytes(sequenceNumber)); // Sequence number
baos.write(intToBytes(width)); // Width
baos.write(intToBytes(height)); // Height
baos.write(intToBytes(delayMs)); // Delay numerator
baos.write(intToBytes(1000)); // Delay denominator
baos.write(0); // Dispose op
baos.write(0); // Blend op
byte[] chunkData = baos.toByteArray();
baos.write(intToBytes(crc32(chunkData, 4, chunkData.length - 4))); // CRC
return baos.toByteArray();
}
private static byte[] createIDATChunk(BufferedImage image) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, "png", baos);
byte[] pngData = baos.toByteArray();
// Extract IDAT chunk from PNG data
int idatStart = findChunk(pngData, "IDAT");
if (idatStart == -1) {
throw new IOException("IDAT chunk not found in PNG data");
}
// Extract the IDAT chunk (length + type + data + CRC)
int length = ByteBuffer.wrap(pngData, idatStart - 4, 4).order(ByteOrder.BIG_ENDIAN).getInt();
byte[] idatChunk = new byte[length + 12]; // 4 (length) + 4 (type) + length (data) + 4 (CRC)
System.arraycopy(pngData, idatStart - 4, idatChunk, 0, idatChunk.length);
return idatChunk;
}
private static byte[] createFDATChunk(int sequenceNumber, byte[] imageData) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(intToBytes(imageData.length - 8)); // fdAT data length (excluding sequence number)
baos.write("fdAT".getBytes()); // Chunk type
baos.write(intToBytes(sequenceNumber)); // Sequence number
baos.write(imageData, 8, imageData.length - 8); // Image data (excluding length and type)
byte[] chunkData = baos.toByteArray();
baos.write(intToBytes(crc32(chunkData, 4, chunkData.length - 4))); // CRC
return baos.toByteArray();
}
private static byte[] createIENDChunk() throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(intToBytes(0)); // IEND data length
baos.write("IEND".getBytes()); // Chunk type
byte[] chunkData = baos.toByteArray();
baos.write(intToBytes(crc32(chunkData, 4, chunkData.length - 4))); // CRC
return baos.toByteArray();
}
private static byte[] intToBytes(int value) {
return ByteBuffer.allocate(4).order(ByteOrder.BIG_ENDIAN).putInt(value).array();
}
private static int crc32(byte[] data, int offset, int length) {
CRC32 crc = new CRC32();
crc.update(data, offset, length);
return (int) crc.getValue();
}
private static int findChunk(byte[] pngData, String chunkType) {
byte[] typeBytes = chunkType.getBytes();
for (int i = 8; i < pngData.length - 4; i++) {
if (pngData == typeBytes[0] &&
pngData[i + 1] == typeBytes[1] &&
pngData[i + 2] == typeBytes[2] &&
pngData[i + 3] == typeBytes[3]) {
return i; // Return the start of the chunk type
}
}
return -1; // Chunk not found
}
< /code>
Я использую этот код для генерации анимации APNG, и, хотя процесс, кажется, работает для создания различных кусков (IHDR, ACTL, FCTL, IDAT и т. Д.), Я все еще сталкиваюсь с проблемами с выводом, которые, похоже, не демонстрируют анимацию в качестве ожидаемого. Любой совет о том, как отлаживать или общие ловушки в создании APNG, были бы очень оценены.
Заранее!
Подробнее здесь: https://stackoverflow.com/questions/794 ... -with-java
Поколение APNG с Java ⇐ JAVA
Программисты JAVA общаются здесь
1 сообщение
• Страница 1 из 1
Anonymous
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...