PPTX DOCX XLSX PDF ODP
Aspose.Imaging  för .NET
TIFF

Cartoonify TIFFs via C#

Bygg dina egna .NET-appar för att Cartoonify TIFF-filer med hjälp av API:er på serversidan.

Hur man tecknar TIFF-filer med C#

Tecknade effekter har en inneboende dragningskraft och väcker ofta nostalgiska barndomsminnen. Nästan varje grafisk designartikel integrerar tecknade bilder som ett viktigt element. Att teckna porträtt, finjustera belysning, konvertera till svart och vitt, experimentera med färger, blanda olika redigeringstekniker och skapa sofistikerade bildeffekter är alla möjliga att uppnå med bildfilter som AdjustBrightness, BinarizeFixed, Filter, ReplaceColor och ApplyMask. Dessa filter kan tillämpas på de originalladdade fotona. Oavsett ämnet för din webbsida visar sig bilder i tecknad stil vara lämpliga för illustrationsändamål. En vetenskaplig artikel får liv, medan mångsidigt innehåll blir mer lockande för användarna, vilket ökar webbplatstrafiken. För att Cartoonify TIFF-filer kommer vi att använda Aspose.Imaging for .NET API som är ett funktionsrikt, kraftfullt och lättanvänt API för bildmanipulation och konvertering för C#-plattformen. Öppna NuGet pakethanteraren, sök efter Aspose.Imaging och installera. Du kan också använda följande kommando från Package Manager Console.

Pakethanterarens konsolkommando


PM> Install-Package Aspose.Imaging

Steg för att Cartoonify TIFFs via C#

Du behöver aspose.imaging.dll för att prova följande arbetsflöde i din egen miljö.

  • Ladda TIFF-filer med Image.Load-metoden
  • Cartoonify bilder;
  • Spara komprimerad bild på skiva i det format som stöds av Aspose.Imaging

Systemkrav

Aspose.Imaging för .NET stöds på alla större operativsystem. Se bara till att du har följande förutsättningar.

  • Microsoft Windows eller ett kompatibelt operativsystem med .NET Framework, .NET Core, Windows Application, ASP.NET Web Application.
  • Utvecklingsmiljö som Microsoft Visual Studio.
  • Aspose.Imaging för .NET som refereras till i ditt projekt.
 

Cartoonify TIFF-bilder - .NET

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));
}
}
 
  • Om Aspose.Imaging för .NET API

    Aspose.Imaging API är en bildbehandlingslösning för att skapa, modifiera, rita eller konvertera bilder (foton) i applikationer. Det erbjuder: plattformsoberoende bildbehandling, inklusive men inte begränsat till konverteringar mellan olika bildformat (inklusive enhetlig bildbehandling med flera sidor eller flera ramar), modifieringar som ritning, arbete med grafiska primitiver, transformationer (ändra storlek, beskära, vänd och rotera , binarisering, gråskala, justera), avancerade bildmanipuleringsfunktioner (filtrering, vibrering, maskering, avskedning) och minnesoptimeringsstrategier. Det är ett fristående bibliotek och är inte beroende av någon programvara för bildoperationer. Man kan enkelt lägga till högpresterande bildkonverteringsfunktioner med inbyggda API:er inom projekt. Dessa är 100 % privata API:er på plats och bilder bearbetas på dina servrar.

    Cartoonify TIFFs via onlineappen

    Cartoonify TIFF-dokument genom att besöka vår webbplats för Live Demos . Livedemon har följande fördelar

      Du behöver inte ladda ner eller ställa in någonting
      Du behöver inte skriva någon kod
      Ladda bara upp dina TIFF-filer och tryck på knappen Tecknad serie.
      Skaffa omedelbart nedladdningslänken för den resulterande filen

    TIFF Vad är TIFF Filformat

    TIFF eller TIF, Tagged Image File Format, representerar rasterbilder som är avsedda för användning på en mängd olika enheter som överensstämmer med denna filformatstandard. Den kan beskriva bilevel-, gråskala-, palett-färg- och fullfärgsbilddata i flera färgrymder. Den stöder såväl förlustfria som förlustfria komprimeringssystem för att välja mellan utrymme och tid för applikationer som använder formatet. Formatet är utbyggbart och har genomgått flera revisioner som gör det möjligt att inkludera en obegränsad mängd privat eller specialinformation. Formatet är inte maskinberoende och är fritt från gränser som processor, operativsystem eller filsystem.

    Läs mer

    Andra Cartoonify-format som stöds

    Med hjälp av C# kan man enkelt Cartoonify olika format inklusive.

    APNG (Animerad bärbar nätverksgrafik)
    BMP (Bitmap bild)
    ICO (Windows-ikonen)
    JPG (Förenade Fotografers Expert Grupp)
    JPEG (Förenade Fotografers Expert Grupp)
    DIB (Enhetsoberoende bitmapp)
    DICOM (Digital bildbehandling och kommunikation)
    DJVU (Grafikformat)
    DNG (Digitalkamerabild)
    EMF (Förbättrat metafilformat)
    EMZ (Windows komprimerad förbättrad metafil)
    GIF (Grafiskt utbytesformat)
    JP2 (JPEG 2000)
    J2K (Wavelet komprimerad bild)
    PNG (Bärbar nätverksgrafik)
    TIF (Taggad bildformat)
    WEBP (Raster webbbild)
    WMF (Microsoft Windows metafil)
    WMZ (Komprimerat Windows Media Player-skal)
    TGA (Targa grafik)
    SVG (Skalbar vektorgrafik)
    EPS (Inkapslat PostScript-språk)
    CDR (Vektor Ritning Bild)
    CMX (Corel Exchange-bild)
    OTG (OpenDocument Standard)
    ODG (Apache OpenOffice ritformat)