Cartoonify WMZ per Java
Sukurkite savo Java programas, kad galėtumėte Cartoonify WMZ failus naudodami serverio API.
Kaip animuoti WMZ failus naudojant Java
Animacinių filmų efektams būdingas patrauklumas, dažnai sukeliantis nostalgiškus vaikystės prisiminimus. Beveik kiekviename grafinio dizaino straipsnyje animacinių filmų vaizdai integruojami kaip esminis elementas. Animacinių portretų kūrimas, apšvietimo koregavimas, konvertavimas į juodą ir baltą, eksperimentavimas su spalvomis, įvairių redagavimo technikų maišymas ir sudėtingų vaizdo efektų kūrimas pasiekiami naudojant vaizdo filtrus, tokius kaip AdjustBrightness, BinarizeFixed, Filter, ReplaceColor ir ApplyMask. Šiuos filtrus galima pritaikyti originalioms įkeltoms nuotraukoms. Nepriklausomai nuo jūsų tinklalapio temos, animacinių filmų stiliaus vaizdai yra tinkami iliustracijai. Mokslinis straipsnis įgauna gyvybingumo, o įvairus turinys labiau vilioja vartotojus ir taip padidina svetainės srautą. Siekdami animuoti WMZ failus, naudosime Aspose.Imaging for Java API, kuri yra daug funkcijų, galinga ir lengvai naudojama vaizdo manipuliavimo ir konvertavimo API, skirta Java platformai. Naujausią jos versiją galite atsisiųsti tiesiai iš Maven ir įdiekite jį savo Maven pagrįstame projekte, pridėdami toliau nurodytas konfigūracijas prie pom.xml.
Repository
<repository>
<id>AsposeJavaAPI</id>
<name>Aspose Java API</name>
<url>https://repository.aspose.com/repo/</url>
</repository>
Priklausomybė
<dependency>
<groupId>com.aspose</groupId>
<artifactId>aspose-imaging</artifactId>
<version>version of aspose-imaging API</version>
<classifier>jdk16</classifier>
</dependency>
Karikatūrizavimo WMZ veiksmai naudojant Java
Jums reikia aspose-imaging-version-jdk16.jar norėdami išbandyti šią darbo eigą savo aplinkoje.
- Įkelkite WMZ failus naudodami Image.Load metodą
- Cartoonify vaizdus;
- Išsaugokite suspaustą vaizdą į diską palaikomu Aspose.Imaging formatu
Sistemos reikalavimai
„Aspose.Imaging“, skirta Java, palaikoma visose pagrindinėse operacinėse sistemose. Tiesiog įsitikinkite, kad turite šias būtinas sąlygas.
- Įdiegta JDK 1.6 arba naujesnė versija.
Cartoonify WMZ vaizdai – Java
import com.aspose.imaging.*; | |
import com.aspose.imaging.fileformats.png.PngImage; | |
import com.aspose.imaging.imagefilters.filteroptions.FilterOptionsBase; | |
import com.aspose.imaging.imagefilters.filteroptions.MedianFilterOptions; | |
import com.aspose.imaging.imageoptions.PngOptions; | |
import com.aspose.imaging.masking.ImageMasking; | |
import com.aspose.imaging.masking.options.MaskingOptions; | |
import java.io.File; | |
import java.util.*; | |
import java.util.function.Consumer; | |
import java.util.function.Function; | |
import java.util.stream.Collectors; | |
cartoonify(); | |
public static void cartoonify() | |
{ | |
filterImages(image -> | |
{ | |
try (PngImage processedImage = new PngImage(image)) | |
{ | |
image.resize(image.getWidth() * 2, image.getHeight(), ResizeType.LeftTopToLeftTop); | |
ImageFilterExtensions.cartoonify(processedImage); | |
Graphics gr = new Graphics(image); | |
gr.drawImage(processedImage, processedImage.getWidth(), 0); | |
gr.drawLine(new Pen(Color.getDarkRed(), 3), processedImage.getWidth(), 0, processedImage.getWidth(), image.getHeight()); | |
} | |
}, "cartoonify"); | |
} | |
static String templatesFolder = "D:\\TestData\\"; | |
public static void filterImages(Consumer<RasterImage> doFilter, String filterName) | |
{ | |
List<String> rasterFormats = Arrays.asList("jpg", "png", "bmp", "apng", "dicom", | |
"jp2", "j2k", "tga", "webp", "tif", "gif", "ico"); | |
List<String> vectorFormats = Arrays.asList("svg", "otg", "odg", "eps", "wmf", "emf", "wmz", "emz", "cmx", "cdr"); | |
List<String> allFormats = new LinkedList<>(rasterFormats); | |
allFormats.addAll(vectorFormats); | |
allFormats.forEach( | |
formatExt -> | |
{ | |
String inputFile = templatesFolder + "template." + formatExt; | |
boolean isVectorFormat = vectorFormats.contains(formatExt); | |
//Need to rasterize vector formats before background remove | |
if (isVectorFormat) | |
{ | |
inputFile = rasterizeVectorImage(formatExt, inputFile); | |
} | |
String outputFile = templatesFolder + String.format("%s_%s.png", filterName, formatExt); | |
System.out.println("Processing " + formatExt); | |
try (RasterImage image = (RasterImage) Image.load(inputFile)) | |
{ | |
doFilter.accept(image); | |
//If image is multipage save each page to png to demonstrate results | |
if (image instanceof IMultipageImage && ((IMultipageImage) image).getPageCount() > 1) | |
{ | |
IMultipageImage multiPage = (IMultipageImage) image; | |
final int pageCount = multiPage.getPageCount(); | |
final Image[] pages = multiPage.getPages(); | |
for (int pageIndex = 0; pageIndex < pageCount; pageIndex++) | |
{ | |
String fileName = String.format("%s_page%d_%s.png", filterName, pageIndex, formatExt); | |
pages[pageIndex].save(fileName, new PngOptions()); | |
} | |
} | |
else | |
{ | |
image.save(outputFile, new PngOptions()); | |
} | |
} | |
//Remove rasterized vector image | |
if (isVectorFormat) | |
{ | |
new File(inputFile).delete(); | |
} | |
} | |
); | |
} | |
private static String rasterizeVectorImage(String formatExt, String inputFile) | |
{ | |
String outputFile = templatesFolder + "rasterized." + formatExt + ".png"; | |
try (Image image = Image.load(inputFile)) | |
{ | |
image.save(outputFile, new PngOptions()); | |
} | |
return outputFile; | |
} | |
interface IImageDataContext | |
{ | |
void applyData(); | |
} | |
class ImageFilterExtensions | |
{ | |
public static void cartoonify(RasterImage image) | |
{ | |
try (RasterImage outlines = detectOutlines(image, Color.getBlack())) | |
{ | |
image.adjustBrightness(30); | |
image.filter(image.getBounds(), new MedianFilterOptions(7)); | |
Graphics gr = new Graphics(image); | |
gr.drawImage(outlines, Point.getEmpty()); | |
} | |
} | |
public static RasterImage detectOutlines(RasterImage image, Color outlineColor) | |
{ | |
PngImage outlines = new PngImage(image); | |
IImageDataContext ctx = getDataContext(outlines); | |
applyConvolutionFilter(ctx, ConvolutionFilterOptions.getBlur()); | |
applyConvolutionFilter(ctx, ConvolutionFilterOptions.getOutline()); | |
ctx.applyData(); | |
outlines.binarizeFixed((byte)30); | |
ImageMasking.applyMask(outlines, outlines, new MaskingOptions() | |
{{ | |
setBackgroundReplacementColor(Color.getTransparent()); | |
}}); | |
outlines.replaceColor(Color.fromArgb(255, 255, 255), (byte)0, outlineColor); | |
applyConvolutionFilter(outlines, ConvolutionFilterOptions.getBlur()); | |
return outlines; | |
} | |
public static RasterImage applyOperationToRasterImage(RasterImage image, Consumer<RasterImage> operation) | |
{ | |
if (image instanceof IMultipageImage) | |
{ | |
IMultipageImage multipage = (IMultipageImage) image; | |
for (Image page : multipage.getPages()) | |
{ | |
operation.accept((RasterImage) page); | |
} | |
} | |
else | |
{ | |
operation.accept(image); | |
} | |
return image; | |
} | |
public static RasterImage applyFilter(RasterImage image, FilterOptionsBase filterOptions) | |
{ | |
return applyOperationToRasterImage(image, img -> | |
img.filter(img.getBounds(), filterOptions)); | |
} | |
public static RasterImage applyConvolutionFilter(RasterImage image, ConvolutionFilterOptions filterOptions) | |
{ | |
return applyOperationToRasterImage(image, img -> | |
{ | |
ImagePixelsLoader pixelsLoader = new ImagePixelsLoader(img.getBounds()); | |
img.loadPartialArgb32Pixels(img.getBounds(), pixelsLoader); | |
PixelBuffer outBuffer = new PixelBuffer(img.getBounds(), new int[img.getWidth() * img.getHeight()]); | |
ConvolutionFilter.doFiltering(pixelsLoader.getPixelsBuffer(), outBuffer, filterOptions); | |
img.saveArgb32Pixels(outBuffer.getRectangle(), outBuffer.getPixels()); | |
}); | |
} | |
public static IImageDataContext getDataContext(RasterImage image) | |
{ | |
if (image instanceof IMultipageImage) | |
{ | |
return new MultipageDataContext( | |
Arrays.stream(((IMultipageImage)image).getPages()).map(page -> { | |
ImageDataContext buf = new ImageDataContext((RasterImage) page); | |
buf.setBuffer(getImageBuffer((RasterImage)page)); | |
return buf; | |
}).collect(Collectors.toList())); | |
} | |
ImageDataContext buf = new ImageDataContext(image); | |
buf.setBuffer(getImageBuffer(image)); | |
return buf; | |
} | |
static IPixelBuffer getImageBuffer(RasterImage img) | |
{ | |
ImagePixelsLoader pixelsLoader = new ImagePixelsLoader(img.getBounds()); | |
img.loadPartialArgb32Pixels(img.getBounds(), pixelsLoader); | |
return pixelsLoader.getPixelsBuffer(); | |
} | |
public static IImageDataContext applyToDataContext(IImageDataContext dataContext, | |
Function<IPixelBuffer, IPixelBuffer> processor) | |
{ | |
if (dataContext instanceof MultipageDataContext) | |
{ | |
for (ImageDataContext context : (MultipageDataContext) dataContext) | |
{ | |
context.setBuffer(processor.apply(context.getBuffer())); | |
} | |
} | |
if (dataContext instanceof ImageDataContext) | |
{ | |
ImageDataContext ctx = (ImageDataContext)dataContext; | |
ctx.setBuffer(processor.apply(ctx.getBuffer())); | |
} | |
return dataContext; | |
} | |
public static IImageDataContext applyConvolutionFilter(IImageDataContext dataContext, | |
ConvolutionFilterOptions filterOptions) | |
{ | |
return applyToDataContext(dataContext, buffer -> | |
{ | |
PixelBuffer outBuffer = new PixelBuffer(buffer.getRectangle(), new int[buffer.getRectangle().getWidth() * buffer.getRectangle().getHeight()]); | |
ConvolutionFilter.doFiltering(buffer, outBuffer, filterOptions); | |
return outBuffer; | |
}); | |
} | |
} | |
class ImageDataContext implements IImageDataContext | |
{ | |
private final RasterImage image; | |
private IPixelBuffer buffer; | |
public ImageDataContext(RasterImage image) | |
{ | |
this.image = image; | |
} | |
public RasterImage getImage() | |
{ | |
return image; | |
} | |
public IPixelBuffer getBuffer() | |
{ | |
return buffer; | |
} | |
public void setBuffer(IPixelBuffer buffer) | |
{ | |
this.buffer = buffer; | |
} | |
public void applyData() | |
{ | |
this.buffer.saveToImage(this.image); | |
} | |
} | |
class MultipageDataContext extends LinkedList<ImageDataContext> implements IImageDataContext | |
{ | |
public MultipageDataContext(Collection<ImageDataContext> enumerable) | |
{ | |
addAll(enumerable); | |
} | |
public void applyData() | |
{ | |
for (ImageDataContext context : this) | |
{ | |
context.applyData(); | |
} | |
} | |
} | |
class ImagePixelsLoader implements IPartialArgb32PixelLoader | |
{ | |
private final CompositePixelBuffer pixelsBuffer; | |
public ImagePixelsLoader(Rectangle rectangle) | |
{ | |
this.pixelsBuffer = new CompositePixelBuffer(rectangle); | |
} | |
public CompositePixelBuffer getPixelsBuffer() | |
{ | |
return pixelsBuffer; | |
} | |
@Override | |
public void process(Rectangle pixelsRectangle, int[] pixels, Point start, Point end) | |
{ | |
this.pixelsBuffer.addPixels(pixelsRectangle,pixels); | |
} | |
} | |
interface IPixelBuffer | |
{ | |
Rectangle getRectangle(); | |
int get(int x, int y); | |
void set(int x, int y, int value); | |
void saveToImage(RasterImage image); | |
} | |
class PixelBuffer implements IPixelBuffer | |
{ | |
private final Rectangle rectangle; | |
private final int[] pixels; | |
public PixelBuffer(Rectangle rectangle,int[] pixels) | |
{ | |
this.rectangle = rectangle; | |
this.pixels = pixels; | |
} | |
@Override | |
public com.aspose.imaging.Rectangle getRectangle() | |
{ | |
return rectangle; | |
} | |
public int[] getPixels() | |
{ | |
return pixels; | |
} | |
@Override | |
public int get(int x, int y) | |
{ | |
return pixels[getIndex(x,y)]; | |
} | |
@Override | |
public void set(int x, int y, int value) | |
{ | |
pixels[getIndex(x,y)] = value; | |
} | |
public void saveToImage(RasterImage image) | |
{ | |
image.saveArgb32Pixels(this.rectangle, this.pixels); | |
} | |
public boolean contains(int x,int y) | |
{ | |
return this.rectangle.contains(x,y); | |
} | |
private int getIndex(int x,int y) | |
{ | |
x -= this.rectangle.getLeft(); | |
y -= this.rectangle.getTop(); | |
return x + y * this.rectangle.getWidth(); | |
} | |
} | |
class CompositePixelBuffer implements IPixelBuffer | |
{ | |
private final List<PixelBuffer> _buffers = new ArrayList<>(); | |
private final Rectangle rectangle; | |
public CompositePixelBuffer(Rectangle rectangle) | |
{ | |
this.rectangle = rectangle; | |
} | |
@Override | |
public com.aspose.imaging.Rectangle getRectangle() | |
{ | |
return rectangle; | |
} | |
@Override | |
public int get(int x, int y) | |
{ | |
return getBuffer(x,y).get(x, y); | |
} | |
@Override | |
public void set(int x, int y, int value) | |
{ | |
getBuffer(x, y).set(x, y, value); | |
} | |
@Override | |
public void saveToImage(RasterImage image) | |
{ | |
for (PixelBuffer buffer : this._buffers) | |
{ | |
buffer.saveToImage(image); | |
} | |
} | |
public void addPixels(Rectangle rectangle,int[] pixels) | |
{ | |
if(rectangle.intersectsWith(rectangle)) | |
{ | |
this._buffers.add(new PixelBuffer(rectangle,pixels)); | |
} | |
} | |
private PixelBuffer getBuffer(int x,int y) | |
{ | |
return this._buffers.stream().filter(b -> b.contains(x,y)).findFirst().get(); | |
} | |
} | |
class ConvolutionFilter | |
{ | |
public static void doFiltering( | |
IPixelBuffer inputBuffer, | |
IPixelBuffer outputBuffer, | |
ConvolutionFilterOptions options) | |
{ | |
double factor = options.getFactor(); | |
int bias = options.getBias(); | |
double[][] kernel = options.getKernel(); | |
int filterWidth = kernel[0].length; | |
int filterCenter = (filterWidth - 1) / 2; | |
int x, y; | |
int filterX, filterY, filterPx, filterPy, filterYPos, pixel; | |
double r, g, b, kernelValue; | |
int top = inputBuffer.getRectangle().getTop(); | |
int bottom = inputBuffer.getRectangle().getBottom(); | |
int left = inputBuffer.getRectangle().getLeft(); | |
int right = inputBuffer.getRectangle().getRight(); | |
for (y = top; y < bottom; y++) | |
{ | |
for (x = left; x < right; x++) | |
{ | |
r = 0; | |
g = 0; | |
b = 0; | |
for (filterY = -filterCenter; filterY <= filterCenter; filterY++) | |
{ | |
filterYPos = filterY + filterCenter; | |
filterPy = filterY + y; | |
if (filterPy >= top && filterPy < bottom) | |
{ | |
for (filterX = -filterCenter; filterX <= filterCenter; filterX++) | |
{ | |
filterPx = filterX + x; | |
if (filterPx >= left && filterPx < right) | |
{ | |
kernelValue = kernel[filterYPos][filterX + filterCenter]; | |
pixel = inputBuffer.get(filterPx, filterPy); | |
r += ((pixel >> 16) & 0xFF) * kernelValue; | |
g += ((pixel >> 8) & 0xFF) * kernelValue; | |
b += (pixel & 0xFF) * kernelValue; | |
} | |
} | |
} | |
} | |
r = (factor * r) + bias; | |
g = (factor * g) + bias; | |
b = (factor * b) + bias; | |
r = r > 255 ? 255 : (r < 0 ? 0 : r); | |
g = g > 255 ? 255 : (g < 0 ? 0 : g); | |
b = b > 255 ? 255 : (b < 0 ? 0 : b); | |
outputBuffer.set(x, y, (inputBuffer.get(x, y) & 0xFF000000) | ((int)r << 16) | ((int)g << 8) | (int)b); | |
} | |
} | |
} | |
} | |
class ConvolutionFilterOptions | |
{ | |
private double factor = 1.0; | |
public double getFactor() | |
{ | |
return factor; | |
} | |
public void setFactor(double factor) | |
{ | |
this.factor = factor; | |
} | |
private int bias = 0; | |
public int getBias() | |
{ | |
return bias; | |
} | |
public void setBias(int bias) | |
{ | |
this.bias = bias; | |
} | |
private double[][] kernel; | |
public double[][] getKernel() | |
{ | |
return kernel; | |
} | |
public void setKernel(double[][] kernel) | |
{ | |
this.kernel = kernel; | |
} | |
public ConvolutionFilterOptions() | |
{ | |
} | |
public ConvolutionFilterOptions(double[][] kernel) | |
{ | |
this.kernel = kernel; | |
} | |
public static ConvolutionFilterOptions getBlur() | |
{ | |
ConvolutionFilterOptions filterOptions = new ConvolutionFilterOptions(); | |
filterOptions.setKernel(new double[][] { { 1, 2, 1 }, { 2, 4, 2 }, { 1, 2, 1 } }); | |
filterOptions.setFactor(0.25 * 0.25); | |
return filterOptions; | |
} | |
public static ConvolutionFilterOptions getSharpen() | |
{ | |
return new ConvolutionFilterOptions(new double[][] { { 0, -1, 0 }, { -1, 5, -1 }, { 0, -1, 0 } }); | |
} | |
public static ConvolutionFilterOptions getEmboss() | |
{ | |
return new ConvolutionFilterOptions(new double[][] { { -2, -1, 0 }, { -1, 1, 1 }, { 0, 1, 2 } }); | |
} | |
public static ConvolutionFilterOptions getOutline() | |
{ | |
return new ConvolutionFilterOptions(new double[][] { { -1, -1, -1 }, { -1, 8, -1 }, { -1, -1, -1 } }); | |
} | |
public static ConvolutionFilterOptions getBottomSobel() | |
{ | |
return new ConvolutionFilterOptions(new double[][] { { -1, -2, -1 }, { 0, 0, 0 }, { 1, 2, 1 } }); | |
} | |
public static ConvolutionFilterOptions getTopSobel() | |
{ | |
return new ConvolutionFilterOptions(new double[][] { { 1, 2, 1 }, { 0, 0, 0 }, { -1, -2, -1 } }); | |
} | |
public static ConvolutionFilterOptions getLeftSobel() | |
{ | |
return new ConvolutionFilterOptions(new double[][] { { 1, 0, -1 }, { 2, 0, -2 }, { 1, 0, -1 } }); | |
} | |
public static ConvolutionFilterOptions getRightSobel() | |
{ | |
return new ConvolutionFilterOptions(new double[][] { { -1, 0, 1 }, { -2, 0, 2 }, { -1, 0, 1 } }); | |
} | |
} |
Apie „Aspose.Imaging“, skirta Java API
Aspose.Imaging API yra vaizdo apdorojimo sprendimas, skirtas kurti, modifikuoti, piešti ar konvertuoti vaizdus (nuotraukas) programose. Ji siūlo: kelių platformų vaizdo apdorojimą, įskaitant, bet tuo neapsiribojant, konvertavimą tarp įvairių vaizdo formatų (įskaitant vienodą kelių puslapių arba kelių kadrų vaizdo apdorojimą), modifikacijas, tokias kaip piešimas, darbas su grafiniais primityvais, transformacijos (keisti dydį, apkarpyti, apversti ir pasukti). , dvejetainis, pilkos spalvos tonas, koregavimas), pažangios vaizdo apdorojimo funkcijos (filtravimas, keitimas, maskavimas, iškrypimas) ir atminties optimizavimo strategijos. Tai yra atskira biblioteka ir nepriklauso nuo jokios programinės įrangos vaizdo operacijoms. Projektuose galima lengvai pridėti didelio našumo vaizdo konvertavimo funkcijų naudojant vietines API. Tai yra 100 % privačios vietinės API, o vaizdai apdorojami jūsų serveriuose.Cartoonify WMZ per internetinę programą
Karikatūrizuokite WMZ dokumentus apsilankę tiesioginės demonstracinės versijos svetainėje . Tiesioginė demonstracinė versija turi šiuos privalumus
WMZ Kas yra WMZ Failo formatas
WMZ yra „Windows Media Player“ / „Windows Media Player“ naudojamo odos failo formato failo plėtinys. WMZ failas iš esmės yra suglaudintas WMF failas XML formatu.
Skaityti daugiauKiti palaikomi Cartoonify formatai
Naudojant Java, galima lengvai animuoti įvairius formatus, įskaitant.