mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-12 13:12:16 +00:00
Added: #2504 WebP image format for export/import (not animated)
Limitation: It's not available on Mac x86-64 platform
This commit is contained in:
@@ -63,6 +63,7 @@ import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.Path;
|
||||
import com.jpexs.helpers.SerializableImage;
|
||||
import com.jpexs.helpers.utf8.Utf8Helper;
|
||||
import dev.matrixlab.webp4j.WebPCodec;
|
||||
import gnu.jpdf.PDFGraphics;
|
||||
import gnu.jpdf.PDFJob;
|
||||
import java.awt.AlphaComposite;
|
||||
@@ -120,6 +121,9 @@ public class FrameExporter {
|
||||
case SVG:
|
||||
fem = FrameExportMode.SVG;
|
||||
break;
|
||||
case WEBP:
|
||||
fem = FrameExportMode.WEBP;
|
||||
break;
|
||||
case SWF:
|
||||
fem = FrameExportMode.SWF;
|
||||
break;
|
||||
@@ -160,6 +164,9 @@ public class FrameExporter {
|
||||
case BMP:
|
||||
fem = FrameExportMode.BMP;
|
||||
break;
|
||||
case WEBP:
|
||||
fem = FrameExportMode.WEBP;
|
||||
break;
|
||||
case SWF:
|
||||
fem = FrameExportMode.SWF;
|
||||
break;
|
||||
@@ -513,7 +520,9 @@ public class FrameExporter {
|
||||
}
|
||||
|
||||
final Color fbackgroundColor = backgroundColor;
|
||||
final boolean usesTransparency = settings.mode == FrameExportMode.PNG || settings.mode == FrameExportMode.GIF;
|
||||
final boolean usesTransparency = settings.mode == FrameExportMode.PNG
|
||||
|| settings.mode == FrameExportMode.GIF
|
||||
|| settings.mode == FrameExportMode.WEBP;
|
||||
final MyFrameIterator frameImages = new MyFrameIterator(tim, fframes, evl, usesTransparency, backgroundColor, settings, subFramesLength);
|
||||
|
||||
switch (settings.mode) {
|
||||
@@ -545,6 +554,26 @@ public class FrameExporter {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WEBP:
|
||||
for (File foutdir : foutdirs) {
|
||||
frameImages.reset();
|
||||
for (int i = 0; frameImages.hasNext(); i++) {
|
||||
final int fi = i;
|
||||
new RetryTask(() -> {
|
||||
int fileNum = subFramesLength > 1 ? fi + 1 : (fframes.get(fi) + 1);
|
||||
|
||||
File f = new File(foutdir + File.separator + fileNum + ".webp");
|
||||
BufferedImage img = frameImages.next();
|
||||
if (img != null) {
|
||||
try(FileOutputStream fos = new FileOutputStream(f)) {
|
||||
fos.write(WebPCodec.encodeImage(img, 100f));
|
||||
}
|
||||
}
|
||||
ret.add(f);
|
||||
}, handler).run();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PNG:
|
||||
for (File foutdir : foutdirs) {
|
||||
frameImages.reset();
|
||||
|
||||
@@ -33,6 +33,7 @@ import com.jpexs.decompiler.graph.DottedChain;
|
||||
import com.jpexs.helpers.CancellableWorker;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.Path;
|
||||
import dev.matrixlab.webp4j.WebPCodec;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBufferInt;
|
||||
@@ -110,6 +111,11 @@ public class ImageExporter {
|
||||
if (settings.mode == ImageExportMode.BMP) {
|
||||
fileFormat = ImageFormat.BMP;
|
||||
}
|
||||
|
||||
if (settings.mode == ImageExportMode.WEBP) {
|
||||
fileFormat = ImageFormat.WEBP;
|
||||
}
|
||||
|
||||
final File file = new File(outdir + File.separator + Helper.makeFileName(imageTag.getCharacterExportFileName() + "." + ImageHelper.getImageFormatString(fileFormat)));
|
||||
|
||||
final ImageFormat ffileFormat = fileFormat;
|
||||
@@ -121,6 +127,10 @@ public class ImageExporter {
|
||||
}
|
||||
} else if (ffileFormat == ImageFormat.BMP) {
|
||||
BMPFile.saveBitmap(imageTag.getImageCached().getBufferedImage(), file);
|
||||
} else if (ffileFormat == ImageFormat.WEBP) {
|
||||
try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(file))) {
|
||||
fos.write(WebPCodec.encodeImage(imageTag.getImageCached().getBufferedImage(), 100f));
|
||||
}
|
||||
} else {
|
||||
ImageHelper.write(imageTag.getImageCached().getBufferedImage(), ffileFormat, file);
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.Path;
|
||||
import com.jpexs.helpers.SerializableImage;
|
||||
import com.jpexs.helpers.utf8.Utf8Helper;
|
||||
import dev.matrixlab.webp4j.WebPCodec;
|
||||
import java.awt.Graphics2D;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@@ -158,6 +159,7 @@ public class MorphShapeExporter {
|
||||
break;
|
||||
case PNG_START_END:
|
||||
case BMP_START_END:
|
||||
case WEBP_START_END:
|
||||
double unzoom = settings.zoom;
|
||||
st = mst.getStartShapeTag();
|
||||
rect = st.getRect();
|
||||
@@ -178,6 +180,10 @@ public class MorphShapeExporter {
|
||||
st.toImage(0, 0, 0, new RenderContext(), img, img, false, m, m, m, m, new CXFORMWITHALPHA(), unzoom, false, new ExportRectangle(rect), new ExportRectangle(rect), true, Timeline.DRAW_MODE_ALL, 0, true);
|
||||
if (settings.mode == MorphShapeExportMode.PNG_START_END) {
|
||||
ImageHelper.write(img.getBufferedImage(), ImageFormat.PNG, fileStart);
|
||||
} else if (settings.mode == MorphShapeExportMode.WEBP_START_END) {
|
||||
try(FileOutputStream fos = new FileOutputStream(fileStart)) {
|
||||
fos.write(WebPCodec.encodeImage(img.getBufferedImage(), 100f));
|
||||
}
|
||||
} else {
|
||||
BMPFile.saveBitmap(img.getBufferedImage(), fileStart);
|
||||
}
|
||||
@@ -201,6 +207,10 @@ public class MorphShapeExporter {
|
||||
st.toImage(0, 0, 0, new RenderContext(), img, img, false, m, m, m, m, new CXFORMWITHALPHA(), unzoom, false, new ExportRectangle(rect), new ExportRectangle(rect), true, Timeline.DRAW_MODE_ALL, 0, true);
|
||||
if (settings.mode == MorphShapeExportMode.PNG_START_END) {
|
||||
ImageHelper.write(img.getBufferedImage(), ImageFormat.PNG, fileEnd);
|
||||
} else if (settings.mode == MorphShapeExportMode.WEBP_START_END) {
|
||||
try(FileOutputStream fos = new FileOutputStream(fileEnd)) {
|
||||
fos.write(WebPCodec.encodeImage(img.getBufferedImage(), 100f));
|
||||
}
|
||||
} else {
|
||||
BMPFile.saveBitmap(img.getBufferedImage(), fileEnd);
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.Path;
|
||||
import com.jpexs.helpers.SerializableImage;
|
||||
import com.jpexs.helpers.utf8.Utf8Helper;
|
||||
import dev.matrixlab.webp4j.WebPCodec;
|
||||
import java.awt.Graphics2D;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@@ -122,6 +123,7 @@ public class ShapeExporter {
|
||||
break;
|
||||
case PNG:
|
||||
case BMP:
|
||||
case WEBP:
|
||||
int newWidth = (int) (rect.getWidth() * settings.zoom / SWF.unitDivisor) + 1;
|
||||
int newHeight = (int) (rect.getHeight() * settings.zoom / SWF.unitDivisor) + 1;
|
||||
SerializableImage img = new SerializableImage(newWidth, newHeight, SerializableImage.TYPE_INT_ARGB_PRE);
|
||||
@@ -137,6 +139,10 @@ public class ShapeExporter {
|
||||
st.toImage(0, 0, 0, new RenderContext(), img, img, false, m, m, m, m, new CXFORMWITHALPHA(), unzoom, false, new ExportRectangle(rect), new ExportRectangle(rect), true, Timeline.DRAW_MODE_ALL, 0, true);
|
||||
if (settings.mode == ShapeExportMode.PNG) {
|
||||
ImageHelper.write(img.getBufferedImage(), ImageFormat.PNG, file);
|
||||
} else if (settings.mode == ShapeExportMode.WEBP) {
|
||||
try(FileOutputStream fos = new FileOutputStream(file)) {
|
||||
fos.write(WebPCodec.encodeImage(img.getBufferedImage(), 100f));
|
||||
}
|
||||
} else {
|
||||
BMPFile.saveBitmap(img.getBufferedImage(), file);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.exporters.modes;
|
||||
|
||||
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
|
||||
|
||||
/**
|
||||
* Button export mode.
|
||||
*
|
||||
@@ -34,8 +36,19 @@ public enum ButtonExportMode {
|
||||
* BMP - Windows Bitmap
|
||||
*/
|
||||
BMP,
|
||||
/**
|
||||
* WEBP
|
||||
*/
|
||||
WEBP,
|
||||
/**
|
||||
* SWF - Shockwave Flash
|
||||
*/
|
||||
SWF,
|
||||
SWF;
|
||||
|
||||
public boolean available() {
|
||||
if (this == WEBP) {
|
||||
return ImageFormat.WEBP.available();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.exporters.modes;
|
||||
|
||||
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
|
||||
|
||||
/**
|
||||
* Frame export mode.
|
||||
*
|
||||
@@ -50,8 +52,19 @@ public enum FrameExportMode {
|
||||
* BMP - Windows Bitmap
|
||||
*/
|
||||
BMP,
|
||||
/**
|
||||
* WEBP
|
||||
*/
|
||||
WEBP,
|
||||
/**
|
||||
* SWF - Shockwave Flash
|
||||
*/
|
||||
SWF,
|
||||
SWF;
|
||||
|
||||
public boolean available() {
|
||||
if (this == WEBP) {
|
||||
return ImageFormat.WEBP.available();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.exporters.modes;
|
||||
|
||||
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
|
||||
|
||||
/**
|
||||
* Image export mode.
|
||||
*
|
||||
@@ -42,5 +44,16 @@ public enum ImageExportMode {
|
||||
/**
|
||||
* PNG, GIF or JPEG, depending on what suits the best, plus alpha channel
|
||||
*/
|
||||
PNG_GIF_JPEG_ALPHA
|
||||
PNG_GIF_JPEG_ALPHA,
|
||||
/*
|
||||
* WEBP
|
||||
*/
|
||||
WEBP;
|
||||
|
||||
public boolean available() {
|
||||
if (this == WEBP) {
|
||||
return ImageFormat.WEBP.available();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.exporters.modes;
|
||||
|
||||
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
|
||||
|
||||
/**
|
||||
* Morph shape export mode.
|
||||
*
|
||||
@@ -44,10 +46,21 @@ public enum MorphShapeExportMode {
|
||||
* BMP start and end frames - Windows Bitmap
|
||||
*/
|
||||
BMP_START_END,
|
||||
/**
|
||||
* WEBP start and end frames
|
||||
*/
|
||||
WEBP_START_END,
|
||||
//GIF,
|
||||
//AVI,
|
||||
/**
|
||||
* SWF - Shockwave Flash
|
||||
*/
|
||||
SWF,
|
||||
SWF;
|
||||
|
||||
public boolean available() {
|
||||
if (this == WEBP_START_END) {
|
||||
return ImageFormat.WEBP.available();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.exporters.modes;
|
||||
|
||||
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
|
||||
|
||||
/**
|
||||
* Shape export mode.
|
||||
*
|
||||
@@ -38,8 +40,19 @@ public enum ShapeExportMode {
|
||||
* BMP - Windows Bitmap
|
||||
*/
|
||||
BMP,
|
||||
/**
|
||||
* WEBP
|
||||
*/
|
||||
WEBP,
|
||||
/**
|
||||
* SWF - Shockwave Flash
|
||||
*/
|
||||
SWF,
|
||||
SWF;
|
||||
|
||||
public boolean available() {
|
||||
if (this == WEBP) {
|
||||
return ImageFormat.WEBP.available();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.exporters.modes;
|
||||
|
||||
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
|
||||
|
||||
/**
|
||||
* Sprite export mode.
|
||||
*
|
||||
@@ -50,8 +52,19 @@ public enum SpriteExportMode {
|
||||
* BMP - Windows Bitmap
|
||||
*/
|
||||
BMP,
|
||||
/**
|
||||
* WEBP
|
||||
*/
|
||||
WEBP,
|
||||
/**
|
||||
* SWF - Shockwave Flash
|
||||
*/
|
||||
SWF,
|
||||
SWF;
|
||||
|
||||
public boolean available() {
|
||||
if (this == WEBP) {
|
||||
return ImageFormat.WEBP.available();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,6 +60,8 @@ public class MorphShapeExportSettings {
|
||||
return ".png";
|
||||
case BMP_START_END:
|
||||
return ".bmp";
|
||||
case WEBP_START_END:
|
||||
return ".webp";
|
||||
case SVG:
|
||||
case SVG_START_END:
|
||||
return ".svg";
|
||||
|
||||
@@ -64,6 +64,8 @@ public class ShapeExportSettings {
|
||||
return ".bmp";
|
||||
case CANVAS:
|
||||
return ".html";
|
||||
case WEBP:
|
||||
return ".webp";
|
||||
case SWF:
|
||||
return ".swf";
|
||||
default:
|
||||
|
||||
@@ -226,6 +226,8 @@ public class ImageHelper {
|
||||
return "png";
|
||||
case BMP:
|
||||
return "bmp";
|
||||
case WEBP:
|
||||
return "webp";
|
||||
}
|
||||
|
||||
throw new Error("Unsupported image format: " + format);
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.CancellableWorker;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import dev.matrixlab.webp4j.WebPCodec;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
@@ -77,6 +78,20 @@ public class ImageImporter extends TagImporter {
|
||||
ImageHelper.write(b, ImageFormat.PNG, baos);
|
||||
newData = baos.toByteArray();
|
||||
}
|
||||
if (newData.length >= 4
|
||||
&& newData[0] == 'R'
|
||||
&& newData[1] == 'I'
|
||||
&& newData[2] == 'F'
|
||||
&& newData[3] == 'F')
|
||||
{
|
||||
if (!ImageFormat.WEBP.available()) {
|
||||
throw new RuntimeException("WEBP format is not supported on your platform");
|
||||
}
|
||||
BufferedImage b = WebPCodec.decodeImage(newData);
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ImageHelper.write(b, ImageFormat.PNG, baos);
|
||||
newData = baos.toByteArray();
|
||||
}
|
||||
|
||||
if (tagType == 0) {
|
||||
if (it instanceof DefineBitsTag) {
|
||||
@@ -94,7 +109,7 @@ public class ImageImporter extends TagImporter {
|
||||
&& newData[3] == (byte) 0xe0) {
|
||||
tagType = DefineBitsJPEG2Tag.ID;
|
||||
} else {
|
||||
tagType = DefineBitsLosslessTag.ID;
|
||||
tagType = DefineBitsLossless2Tag.ID;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,10 +38,12 @@ import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE;
|
||||
import com.jpexs.helpers.CancellableWorker;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import dev.matrixlab.webp4j.WebPCodec;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@@ -162,6 +164,21 @@ public class ShapeImporter {
|
||||
ImageHelper.write(b, ImageFormat.PNG, baos);
|
||||
newData = baos.toByteArray();
|
||||
}
|
||||
|
||||
if (newData.length >= 4
|
||||
&& newData[0] == 'R'
|
||||
&& newData[1] == 'I'
|
||||
&& newData[2] == 'F'
|
||||
&& newData[3] == 'F')
|
||||
{
|
||||
if (!ImageFormat.WEBP.available()) {
|
||||
throw new RuntimeException("WEBP format is not supported on your platform");
|
||||
}
|
||||
BufferedImage b = WebPCodec.decodeImage(newData);
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ImageHelper.write(b, ImageFormat.PNG, baos);
|
||||
newData = baos.toByteArray();
|
||||
}
|
||||
|
||||
if (tagType == 0) {
|
||||
if (ImageTag.getImageFormat(newData) == ImageFormat.JPEG) {
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags.enums;
|
||||
|
||||
import dev.matrixlab.webp4j.NativeWebP;
|
||||
import dev.matrixlab.webp4j.WebPCodec;
|
||||
|
||||
/**
|
||||
* Image format.
|
||||
*
|
||||
@@ -42,7 +45,11 @@ public enum ImageFormat {
|
||||
/**
|
||||
* BMP
|
||||
*/
|
||||
BMP(".bmp");
|
||||
BMP(".bmp"),
|
||||
/**
|
||||
* WEBP
|
||||
*/
|
||||
WEBP(".webp");
|
||||
|
||||
private final String extension;
|
||||
|
||||
@@ -57,4 +64,15 @@ public enum ImageFormat {
|
||||
public String getExtension() {
|
||||
return extension;
|
||||
}
|
||||
|
||||
public boolean available() {
|
||||
if (this == WEBP) {
|
||||
try {
|
||||
new NativeWebP();
|
||||
} catch (Throwable t) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user