PPTX DOCX XLSX PDF ODP
Aspose.Imaging  pro Java
APNG

Kreslená pohádka APNGs prostřednictvím Java

Vytvářejte své vlastní aplikace Java pro Kreslená pohádka APNG souborů pomocí rozhraní API na straně serveru.

Jak karikaturovat soubory APNG pomocí Java

Kreslené efekty mají neodmyslitelnou přitažlivost a často vyvolávají nostalgické vzpomínky z dětství. Téměř každý článek o grafickém designu integruje kreslené obrázky jako základní prvek. Kreslení portrétů, jemné doladění osvětlení, převod na černobílou, experimentování s barvami, míchání různých technik úprav a vytváření sofistikovaných obrazových efektů – to vše lze dosáhnout pomocí obrazových filtrů, jako je AdjustBrightness, BinarizeFixed, Filter, ReplaceColor a ApplyMask. Tyto filtry lze použít na původní načtené fotografie. Bez ohledu na téma vaší webové stránky se obrázky ve stylu kreslených filmů ukáží jako vhodné pro ilustrační účely. Vědecký článek získává na živosti, zatímco různorodý obsah se stává pro uživatele lákavějším, čímž se zvyšuje návštěvnost webu. Abychom Cartoonify APNG soubory, použijeme Aspose.Imaging for Java API, které je funkčně bohaté, výkonné a snadno použitelné rozhraní API pro manipulaci a konverzi obrázků pro platformu Java. Jeho nejnovější verzi si můžete stáhnout přímo z Maven a nainstalovat do svého Maven -založený projekt přidáním následujících konfigurací do souboru pom.xml.

Úložiště

<repository>
<id>AsposeJavaAPI</id>
<name>Aspose Java API</name>
<url>https://repository.aspose.com/repo/</url>
</repository>

Závislost

<dependency>
<groupId>com.aspose</groupId>
<artifactId>aspose-imaging</artifactId>
<version>version of aspose-imaging API</version>
<classifier>jdk16</classifier>
</dependency>

Kroky ke kreslení APNGs přes Java

Abyste mohli vyzkoušet následující pracovní postup ve svém vlastním prostředí, potřebujete aspose-imaging-version-jdk16.jar .

  • Načíst soubory APNG metodou Image.Load
  • Kreslená pohádka obrázky;
  • Uložte komprimovaný obrázek na disk ve formátu podporovaném Aspose.Imaging

Požadavky na systém

Aspose.Imaging pro Java je podporován ve všech hlavních operačních systémech. Jen se ujistěte, že máte následující předpoklady.

  • Je nainstalován JDK 1.6 nebo vyšší.
 

Obrázky Kreslená pohádka APNG – 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 } });
}
}
 
  • O Aspose.Imaging pro Java API

    Aspose.Imaging API je řešení pro zpracování obrázků pro vytváření, úpravu, kreslení nebo konverzi obrázků (fotografií) v rámci aplikací. Nabízí: multiplatformní zpracování obrazu, mimo jiné včetně převodů mezi různými formáty obrázků (včetně jednotného vícestránkového nebo vícesnímkového zpracování obrazu), úpravy jako kreslení, práci s grafickými primitivy, transformace (změna velikosti, oříznutí, převrácení a otočení). binarizace, stupně šedi, úprava), pokročilé funkce pro manipulaci s obrázky (filtrování, rozklad, maskování, vyrovnání sklonu) a strategie optimalizace paměti. Je to samostatná knihovna a není závislá na žádném softwaru pro operace s obrázky. V rámci projektů lze snadno přidat vysoce výkonné funkce pro konverzi obrázků s nativními rozhraními API. Jedná se o 100% soukromá on-premise API a obrázky se zpracovávají na vašich serverech.

    Kreslená pohádka APNGs prostřednictvím online aplikace

    Kreslená pohádka APNG dokumenty na našem webu s živými ukázkami . Živé demo má následující výhody

      Není třeba nic stahovat ani nastavovat
      Není třeba psát žádný kód
      Stačí nahrát své soubory ve formátu APNG a stisknout tlačítko Kreslená pohádka.
      Okamžitě získejte odkaz ke stažení výsledného souboru

    APNG co je APNG Formát souboru

    Soubor s příponou .apng (Animated Portable Network Graphics) je rastrový grafický formát a je neoficiálním rozšířením Portable Network Graphic (PNG). Skládá se z několika snímků (každý z obrázku PNG), které představují sekvenci animace. To poskytuje podobnou vizualizaci jako soubor GIF. Soubory APNG podporují 24bitové obrázky a 8bitovou průhlednost. APNG je zpětně kompatibilní s neanimovanými soubory GIF. Soubory APNG používají stejnou příponu .png a lze je otevřít aplikacemi, jako je Mozilla Firefox, Chrome s podporou APNG, aplikace iMessage pro iOS 10.

    Přečtěte si více

    Další podporované formáty Kreslená pohádka

    Pomocí Java lze snadno kreslit různé formáty včetně.

    BMP (Bitmapový obrázek)
    ICO (ikona Windows)
    JPG (Společná skupina fotografických expertů)
    JPEG (Společná skupina fotografických expertů)
    DIB (Bitmap nezávislý na zařízení)
    DICOM (Digitální zobrazování a komunikace)
    DJVU (Grafický formát)
    DNG (Obrázek z digitálního fotoaparátu)
    EMF (Vylepšený formát metasouborů)
    EMZ (Windows Compressed Enhanced Metafile)
    GIF (Grafický výměnný formát)
    JP2 (JPEG 2000)
    J2K (Wavelet Compressed Image)
    PNG (Přenosná síťová grafika)
    TIFF (Formát tagovaného obrázku)
    TIF (Formát tagovaného obrázku)
    WEBP (Rastrový webový obrázek)
    WMF (Microsoft Windows Metafile)
    WMZ (Komprimovaný vzhled Windows Media Player)
    TGA (Grafika Targa)
    SVG (Škálovatelná vektorová grafika)
    EPS (Encapsulated PostScript Language)
    CDR (Vektorové Kreslení Obrázek)
    CMX (Obrázek Corel Exchange)
    OTG (OpenDocument Standard)
    ODG (Formát Apache OpenOffice Draw)