PPTX DOCX XLSX PDF ODP
Aspose.Imaging  voor Python
WMF

Gebruik Python voor cartoonachtige afbeeldingen in WMF

Maak Python-apps om WMF-afbeeldingen en -foto’s te cartoonificeren via server-API’s

Hoe u WMF-afbeeldingen en -foto's cartoonificeert met Python

We reageren automatisch op cartoonafbeeldingen omdat ze een gevoel van nostalgie kunnen oproepen. Op het gebied van grafisch ontwerp dienen afbeeldingen in cartoonstijl als cruciale elementen die vaak worden gezien in marketingartikelen. Dit Cartoonify-effect omvat het omzetten van fotoportretten in handgetekende weergaven, het aanpassen van de helderheid, het converteren naar zwart-wit, het spelen met kleurenpaletten en het samenvoegen van verschillende bewerkingstechnieken om ingewikkelde visuele effecten te creëren. Een reeks afbeeldingsfilters, waaronder ‘AdjustBrightness’, ‘BinarizeFixed’, ‘Filter’, ‘ReplaceColor’ en ‘ApplyMask’, stelt gebruikers in staat deze transformaties te realiseren. Deze filters kunnen worden gebruikt op afbeeldingen in origineel formaat en op foto’s die zijn gedownload. Beeldmateriaal in cartoonstijl is geschikt voor illustratiedoeleinden op diverse webpagina’s, waardoor wetenschappelijke artikelen vitaliteit krijgen en de inhoud aantrekkelijker wordt voor gebruikers, waardoor er meer verkeer naar de site wordt geleid. Om cartooneffecten te genereren met behulp van WMF-afbeeldingen, gebruiken we Aspose.Imaging for Python via .NET API, een veelzijdige, krachtige en gebruiksvriendelijke API voor beeldmanipulatie en conversie voor het Python-platform. U kunt het installeren met behulp van de volgende opdracht van uw systeemopdracht.

De systeemopdrachtregel

>> pip install aspose-imaging-python-net

Stappen voor Cartoonify WMFs via Python

U hebt de aspose-imaging-python-net nodig om de volgende workflow in uw eigen omgeving uit te proberen.

  • Laad WMF-bestanden met de methode Image.Load
  • Cartoonify-afbeeldingen;
  • Bewaar gecomprimeerde afbeelding op schijf in het formaat dat wordt ondersteund door Aspose.Imaging

systeem vereisten

Aspose.Imaging voor Python wordt ondersteund op alle belangrijke besturingssystemen. Zorg ervoor dat u aan de volgende vereisten voldoet.

  • Microsoft Windows / Linux met .NET Core Runtime.
  • Python en PyPi pakketbeheerder.
 

Cartoonify WMF afbeeldingen - Python

using Aspose.Imaging;
using Aspose.Imaging.FileFormats.Png;
using Aspose.Imaging.ImageFilters.FilterOptions;
using Aspose.Imaging.ImageOptions;
using Aspose.Imaging.Masking;
using Aspose.Imaging.Masking.Options;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
string templatesFolder = @"c:\Users\USER\Downloads";
Cartoonify();
void Cartoonify()
{
FilterImages(image =>
{
using (var processedImage = new PngImage(image))
{
image.Resize(image.Width * 2, image.Height, ResizeType.LeftTopToLeftTop);
processedImage.Cartoonify();
var gr = new Graphics(image);
gr.DrawImage(processedImage, processedImage.Width, 0);
gr.DrawLine(new Pen(Color.DarkRed, 3), processedImage.Width, 0, processedImage.Width, image.Height);
}
}, "cartoonify");
}
string RasterizeVectorImage(string formatExt, string inputFile)
{
string outputFile = Path.Combine(templatesFolder, $"rasterized.{formatExt}.png");
using (var image = Image.Load(inputFile))
{
image.Save(outputFile, new PngOptions());
}
return outputFile;
}
void FilterImages(Action<RasterImage> doFilter, string filterName)
{
List<string> rasterFormats = new List<string>() { "jpg", "png", "bmp", "apng", "dicom",
"jp2", "j2k", "tga", "webp", "tif", "gif", "ico" };
List<string> vectorFormats = new List<string>() { "svg", "otg", "odg", "eps", "wmf", "emf", "wmz", "emz", "cmx", "cdr" };
List<string> allFormats = new List<string>(rasterFormats);
allFormats.AddRange(vectorFormats);
allFormats.ForEach(
formatExt =>
{
var inputFile = Path.Combine(templatesFolder, $"template.{formatExt}");
bool isVectorFormat = vectorFormats.IndexOf(formatExt) > -1;
//Need to rasterize vector formats before background remove
if (isVectorFormat)
{
inputFile = RasterizeVectorImage(formatExt, inputFile);
}
var outputFile = Path.Combine(templatesFolder, $"{filterName}_{formatExt}.png");
Console.WriteLine($"Processing {formatExt}");
using (var image = (RasterImage)Image.Load(inputFile))
{
doFilter(image);
//If image is multipage save each page to png to demonstrate results
if (image is IMultipageImage multiPage && multiPage.PageCount > 1)
{
for (var pageIndex = 0; pageIndex < multiPage.PageCount; pageIndex++)
{
string fileName = $"{filterName}_page{pageIndex}_{formatExt}.png";
multiPage.Pages[pageIndex].Save(templatesFolder + fileName, new PngOptions());
File.Delete(templatesFolder + fileName);
}
}
else
{
image.Save(outputFile, new PngOptions());
File.Delete(outputFile);
}
}
//Remove rasterized vector image
if (isVectorFormat)
{
File.Delete(inputFile);
}
}
);
}
static class ImageFilterExtensions
{
public static void Cartoonify(this RasterImage image)
{
using var outlines = image.DetectOutlines(Color.Black);
image.AdjustBrightness(30);
image.Filter(image.Bounds, new MedianFilterOptions(7));
var gr = new Graphics(image);
gr.DrawImage(outlines, Point.Empty);
}
public static RasterImage DetectOutlines(this RasterImage image, Color outlineColor)
{
var outlines = new PngImage(image);
outlines
.GetDataContext()
.ApplyConvolutionFilter(ConvolutionFilterOptions.Blur)
.ApplyConvolutionFilter(ConvolutionFilterOptions.Outline)
.ApplyData();
outlines.BinarizeFixed(30);
ImageMasking.ApplyMask(outlines, outlines, new MaskingOptions() { BackgroundReplacementColor = Color.Transparent });
outlines.ReplaceColor(Color.FromArgb(255, 255, 255), 0, outlineColor);
outlines.ApplyConvolutionFilter(ConvolutionFilterOptions.Blur);
return outlines;
}
public static RasterImage ApplyOperationToRasterImage(this RasterImage image, Action<RasterImage> operation)
{
if (image is IMultipageImage multipage)
{
foreach (var page in multipage.Pages)
{
operation.Invoke((RasterImage)page);
}
}
else
{
operation.Invoke(image);
}
return image;
}
public static RasterImage ApplyFilter(this RasterImage image, FilterOptionsBase filterOptions)
{
return image.ApplyOperationToRasterImage(img =>
{
img.Filter(img.Bounds, filterOptions);
});
}
public static RasterImage ApplyConvolutionFilter(this RasterImage image, ConvolutionFilterOptions filterOptions)
{
return image.ApplyOperationToRasterImage(img =>
{
var pixelsLoader = new ImagePixelsLoader(img.Bounds);
img.LoadPartialArgb32Pixels(img.Bounds, pixelsLoader);
var outBuffer = new PixelBuffer(img.Bounds, new int[img.Width * img.Height]);
ConvolutionFilter.DoFiltering(pixelsLoader.PixelsBuffer, outBuffer, filterOptions);
img.SaveArgb32Pixels(outBuffer.Rectangle, outBuffer.Pixels);
});
}
public static IImageDataContext GetDataContext(this RasterImage image)
{
IPixelBuffer GetImageBuffer(RasterImage img)
{
var pixelsLoader = new ImagePixelsLoader(img.Bounds);
img.LoadPartialArgb32Pixels(img.Bounds, pixelsLoader);
return pixelsLoader.PixelsBuffer;
}
if (image is IMultipageImage multipage)
{
return new MultipageDataContext(
multipage.Pages.Select(page => new ImageDataContext((RasterImage)page)
{
Buffer = GetImageBuffer((RasterImage)page)
}));
}
return new ImageDataContext(image)
{
Buffer = GetImageBuffer(image)
};
}
public static IImageDataContext ApplyToDataContext(this IImageDataContext dataContext,
Func<IPixelBuffer, IPixelBuffer> processor)
{
if (dataContext is MultipageDataContext multipage)
{
foreach (var context in multipage)
{
context.Buffer = processor.Invoke(context.Buffer);
}
}
if (dataContext is ImageDataContext imageDataContext)
{
imageDataContext.Buffer = processor.Invoke(imageDataContext.Buffer);
}
return dataContext;
}
public static IImageDataContext ApplyConvolutionFilter(this IImageDataContext dataContext,
ConvolutionFilterOptions filterOptions)
{
return dataContext.ApplyToDataContext(buffer =>
{
var outBuffer = new PixelBuffer(buffer.Rectangle, new int[buffer.Rectangle.Width * buffer.Rectangle.Height]);
ConvolutionFilter.DoFiltering(buffer, outBuffer, filterOptions);
return outBuffer;
});
}
}
class ConvolutionFilter
{
public static void DoFiltering(
IPixelBuffer inputBuffer,
IPixelBuffer outputBuffer,
ConvolutionFilterOptions options)
{
var factor = options.Factor;
var bias = options.Bias;
var kernel = options.Kernel;
var filterWidth = kernel.GetLength(1);
var filterCenter = (filterWidth - 1) / 2;
int x, y;
int filterX, filterY, filterPx, filterPy, filterYPos, pixel;
double r, g, b, kernelValue;
int top = inputBuffer.Rectangle.Top;
int bottom = inputBuffer.Rectangle.Bottom;
int left = inputBuffer.Rectangle.Left;
int right = inputBuffer.Rectangle.Right;
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[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[x, y] = ((inputBuffer[x, y] >> 24) << 24) | ((byte)r << 16) | ((byte)g << 8) | (byte)b;
}
}
}
}
class ConvolutionFilterOptions
{
public double Factor { get; set; } = 1.0;
public int Bias { get; set; } = 0;
public double[,] Kernel { get; set; }
public static ConvolutionFilterOptions Blur
{
get
{
return new ConvolutionFilterOptions
{
Kernel = new double[,] { { 1, 2, 1 }, { 2, 4, 2 }, { 1, 2, 1 } },
Factor = 0.25 * 0.25
};
}
}
public static ConvolutionFilterOptions Sharpen
{
get
{
return new ConvolutionFilterOptions
{
Kernel = new double[,] { { 0, -1, 0 }, { -1, 5, -1 }, { 0, -1, 0 } }
};
}
}
public static ConvolutionFilterOptions Emboss
{
get
{
return new ConvolutionFilterOptions
{
Kernel = new double[,] { { -2, -1, 0 }, { -1, 1, 1 }, { 0, 1, 2 } }
};
}
}
public static ConvolutionFilterOptions Outline
{
get
{
return new ConvolutionFilterOptions
{
Kernel = new double[,] { { -1, -1, -1 }, { -1, 8, -1 }, { -1, -1, -1 } }
};
}
}
public static ConvolutionFilterOptions BottomSobel
{
get
{
return new ConvolutionFilterOptions
{
Kernel = new double[,] { { -1, -2, -1 }, { 0, 0, 0 }, { 1, 2, 1 } }
};
}
}
public static ConvolutionFilterOptions TopSobel
{
get
{
return new ConvolutionFilterOptions
{
Kernel = new double[,] { { 1, 2, 1 }, { 0, 0, 0 }, { -1, -2, -1 } }
};
}
}
public static ConvolutionFilterOptions LeftSobel
{
get
{
return new ConvolutionFilterOptions
{
Kernel = new double[,] { { 1, 0, -1 }, { 2, 0, -2 }, { 1, 0, -1 } }
};
}
}
public static ConvolutionFilterOptions RightSobel
{
get
{
return new ConvolutionFilterOptions
{
Kernel = new double[,] { { -1, 0, 1 }, { -2, 0, 2 }, { -1, 0, 1 } }
};
}
}
}
interface IImageDataContext
{
void ApplyData();
}
class ImageDataContext : IImageDataContext
{
public ImageDataContext(RasterImage image)
{
this.Image = image;
}
public RasterImage Image { get; }
public IPixelBuffer Buffer { get; set; }
public void ApplyData()
{
this.Buffer.SaveToImage(this.Image);
}
}
class MultipageDataContext : List<ImageDataContext>, IImageDataContext
{
public MultipageDataContext(IEnumerable<ImageDataContext> enumerable) : base(enumerable)
{
}
public void ApplyData()
{
foreach (var context in this)
{
context.ApplyData();
}
}
}
class ImagePixelsLoader : IPartialArgb32PixelLoader
{
public ImagePixelsLoader(Aspose.Imaging.Rectangle rectangle)
{
this.PixelsBuffer = new CompositePixelBuffer(rectangle);
}
public CompositePixelBuffer PixelsBuffer { get; }
public void Process(Aspose.Imaging.Rectangle pixelsRectangle, int[] pixels, Point start, Point end)
{
this.PixelsBuffer.AddPixels(pixelsRectangle, pixels);
}
}
interface IPixelBuffer
{
Aspose.Imaging.Rectangle Rectangle { get; }
int this[int x, int y]
{
get;
set;
}
void SaveToImage(RasterImage image);
}
class PixelBuffer : IPixelBuffer
{
public PixelBuffer(Aspose.Imaging.Rectangle rectangle, int[] pixels)
{
this.Rectangle = rectangle;
this.Pixels = pixels;
}
public Aspose.Imaging.Rectangle Rectangle { get; }
public int[] Pixels { get; }
public int this[int x, int y]
{
get => this.Pixels[this.GetIndex(x, y)];
set => this.Pixels[this.GetIndex(x, y)] = value;
}
public void SaveToImage(RasterImage image)
{
image.SaveArgb32Pixels(this.Rectangle, this.Pixels);
}
public bool Contains(int x, int y)
{
return this.Rectangle.Contains(x, y);
}
private int GetIndex(int x, int y)
{
x -= this.Rectangle.Left;
y -= this.Rectangle.Top;
return x + y * this.Rectangle.Width;
}
}
class CompositePixelBuffer : IPixelBuffer
{
private readonly List<PixelBuffer> _buffers = new List<PixelBuffer>();
public CompositePixelBuffer(Aspose.Imaging.Rectangle rectangle)
{
this.Rectangle = rectangle;
}
public Aspose.Imaging.Rectangle Rectangle { get; }
public int this[int x, int y]
{
get => this.GetBuffer(x, y)[x, y];
set => this.GetBuffer(x, y)[x, y] = value;
}
public void SaveToImage(RasterImage image)
{
foreach (var pixelBuffer in this._buffers)
{
pixelBuffer.SaveToImage(image);
}
}
public IEnumerable<PixelBuffer> Buffers => this._buffers;
public void AddPixels(Aspose.Imaging.Rectangle rectangle, int[] pixels)
{
if (this.Rectangle.IntersectsWith(rectangle))
{
this._buffers.Add(new PixelBuffer(rectangle, pixels));
}
}
private PixelBuffer GetBuffer(int x, int y)
{
return this._buffers.First(b => b.Contains(x, y));
}
}
 
  • Over Aspose.Imaging voor Python API

    Aspose.Imaging API is een beeldverwerkingsoplossing voor het maken, wijzigen, tekenen of converteren van afbeeldingen (foto’s) binnen applicaties. Het biedt: platformonafhankelijke beeldverwerking, inclusief maar niet beperkt tot conversies tussen verschillende beeldformaten (inclusief uniforme beeldverwerking van meerdere pagina’s of meerdere frames), aanpassingen zoals tekenen, werken met grafische primitieven, transformaties (formaat wijzigen, bijsnijden, spiegelen en roteren , binarisatie, grijswaarden, aanpassen), geavanceerde functies voor beeldmanipulatie (filteren, dithering, maskeren, rechtzetten) en strategieën voor geheugenoptimalisatie. Het is een op zichzelf staande bibliotheek en is niet afhankelijk van software voor beeldbewerkingen. Men kan eenvoudig hoogwaardige functies voor beeldconversie toevoegen met native API’s binnen projecten. Dit zijn 100% private on-premise API’s en afbeeldingen worden verwerkt op uw servers.

    Cartoonify WMFs via online app

    Cartoonify WMF-documenten door naar onze website met live demo’s te gaan. De live demo heeft de volgende voordelen:

      U hoeft niets te downloaden of in te stellen
      U hoeft geen code te schrijven
      Upload gewoon uw WMF-bestanden en druk op de knop "Cartoonify now"
      Krijg direct de downloadlink voor het resulterende bestand

    WMF Wat is WMF Bestandsformaat

    Bestanden met de WMF-extensie vertegenwoordigen Microsoft Windows Metafile (WMF) voor het opslaan van zowel vector- als bitmap-afbeeldingsgegevens. Om nauwkeuriger te zijn, WMF behoort tot de vectorbestandsindelingscategorie van Grafische bestandsindelingen die apparaatonafhankelijk is. Windows Graphical Device Interface (GDI) gebruikt de functies die zijn opgeslagen in een WMF-bestand om een ​​afbeelding op het scherm weer te geven. Een meer verbeterde versie van WMF, bekend als Enhanced Meta Files (EMF), werd later gepubliceerd, waardoor het formaat meer functies heeft. In de praktijk is WMF vergelijkbaar met SVG.

    Lees verder

    Andere ondersteunde Cartoonify-indelingen

    Met behulp van Python kan men gemakkelijk verschillende formaten Cartoonificeren, waaronder.

    APNG (Geanimeerde draagbare netwerkgraphics)
    BMP (Bitmapafbeelding)
    ICO (Windows-pictogram)
    JPG (Joint Photographic Experts Group)
    JPEG (Joint Photographic Experts Group)
    DIB (Apparaatonafhankelijke bitmap)
    DICOM (Digitale beeldvorming en communicatie)
    DJVU (Grafisch formaat)
    DNG (Digitale Camera Afbeelding)
    EMF (Verbeterde metabestandsindeling)
    EMZ (Windows gecomprimeerd verbeterd metabestand)
    GIF (Grafisch uitwisselingsformaat)
    JP2 (JPEG 2000)
    J2K (Wavelet gecomprimeerde afbeelding)
    PNG (Draagbare netwerkgrafieken)
    TIFF (Gelabelde afbeeldingsindeling)
    TIF (Gelabelde afbeeldingsindeling)
    WEBP (Rasterwebafbeelding)
    WMZ (Gecomprimeerde Windows Media Player-skin)
    TGA (Targa-afbeelding)
    SVG (Schaalbare vectorafbeeldingen)
    EPS (Encapsulated PostScript-taal)
    CDR (Vector tekening afbeelding)
    CMX (Corel Exchange-afbeelding)
    OTG (OpenDocument-standaard)
    ODG (Apache OpenOffice Draw-indeling)