1. 程式人生 > >影象處理控制元件Aspose.Imaging v19.6新版亮點示例詳解(3)

影象處理控制元件Aspose.Imaging v19.6新版亮點示例詳解(3)

Aspose.Imaging for .NET一種高階影象處理控制元件,允許開發人員建立,編輯,繪製或轉換影象。影象匯出和轉換是API核心功能之一,它允許在不安裝Photoshop應用程式或任何其他影象編輯器的情況下儲存為AdobePhotoshop®本機格式。

近期釋出了Aspose.Imaging for .NET v19.6,JPEG輸出中不再保留IMAGINGNET-3351 DPI屬性,下面我們一起來探索新版中的新增功能及其工作原理。>>歡迎下載Aspose.Imaging for .NET v19.6體驗

▲IMAGINGNET-3279 EMF和WMF作物操作提供無效結果

using (EmfImage image = Image.Load("test.emf") as EmfImage)
{
    image.Crop(new Rectangle(10, 10, 100, 150));
    Console.WriteLine(image.Width);
    Console.WriteLine(image.Height);
    image.Save("test.emf_crop.emf");
}
 
using (WmfImage image = Image.Load("test.wmf") as WmfImage)
{
    image.Crop(new Rectangle(10, 10, 100, 150));
    Console.WriteLine(image.Width);
    Console.WriteLine(image.Height);
    image.Save("test.wmf_crop.wmf");
}

 

▲IMAGINGNET-3346 Aspose.Imaging 19.1.0繪圖異常不同格式的影象

Please use the following code to draw a raster image on Wmf image:
 
string dir = "c:\\aspose.work\\IMAGINGNET\\3346\\";
 
// Load the image to be drawn
using (RasterImage imageToDraw = (RasterImage)Image.Load(dir + "asposenet_220_src01.png"))
{
    // Load the image for drawing on it (drawing surface)
    using (WmfImage canvasImage = (WmfImage)Image.Load(dir + "asposenet_222_wmf_200.wmf"))
    {
        WmfRecorderGraphics2D graphics = WmfRecorderGraphics2D.FromWmfImage(canvasImage);
 
        // Draw a rectagular part of the raster image within the specified bounds of the vector image (drawing surface).
        // Note that because the source size is not equal to the destination one, the drawn image is stretched horizontally and vertically.
        graphics.DrawImage(
            imageToDraw,
            new Rectangle(67, 67, canvasImage.Width, canvasImage.Height),
            new Rectangle(0, 0, imageToDraw.Width, imageToDraw.Height),
            GraphicsUnit.Pixel);
 
        // Save the result image
        using (WmfImage resultImage = graphics.EndRecording())
        {
            resultImage.Save(dir + "asposenet_222_wmf_200.DrawImage.wmf");
        }
    }
}

 

Please use the following code to draw a raster image on Emf image:
 
string dir = "c:\\aspose.work\\IMAGINGNET\\3346\\";
 
// Load the image to be drawn
using (RasterImage imageToDraw = (RasterImage)Image.Load(dir + "asposenet_220_src01.png"))
{
    // Load the image for drawing on it (drawing surface)
    using (EmfImage canvasImage = (EmfImage)Image.Load(dir + "input.emf"))
    {
        EmfRecorderGraphics2D graphics = EmfRecorderGraphics2D.FromEmfImage(canvasImage);
 
        // Draw a rectagular part of the raster image within the specified bounds of the vector image (drawing surface).
        // Note that because the source size is not equal to the destination one, the drawn image is stretched horizontally and vertically.
        graphics.DrawImage(
            imageToDraw,
            new Rectangle(67, 67, canvasImage.Width, canvasImage.Height),
            new Rectangle(0, 0, imageToDraw.Width, imageToDraw.Height),
            GraphicsUnit.Pixel);
 
        // Save the result image
        using (EmfImage resultImage = graphics.EndRecording())
        {
            resultImage.Save(dir + "input.DrawImage.emf");
        }
    }
}

 

Please use the following code to draw a raster image on Svg image:
 
string dir = "c:\\aspose.work\\IMAGINGNET\\3346\\";
 
// Load the image to be drawn
using (RasterImage imageToDraw = (RasterImage)Image.Load(dir + "asposenet_220_src01.png"))
{
    // Load the image for drawing on it (drawing surface)
    using (SvgImage canvasImage = (SvgImage)Image.Load(dir + "asposenet_220_src02.svg"))
    {
        // Drawing on an existing Svg image.
        Aspose.Imaging.FileFormats.Svg.Graphics.SvgGraphics2D graphics = new Aspose.Imaging.FileFormats.Svg.Graphics.SvgGraphics2D(canvasImage);
 
        // Draw a rectagular part of the raster image within the specified bounds of the vector image (drawing surface).
        // Note that because the source size is equal to the destination one, the drawn image is not stretched.
        graphics.DrawImage(                        
            new Rectangle(0, 0, imageToDraw.Width, imageToDraw.Height),
            new Rectangle(67, 67, imageToDraw.Width, imageToDraw.Height),
            imageToDraw);
 
        // Save the result image
        using (SvgImage resultImage = graphics.EndRecording())
        {
            resultImage.Save(dir + "asposenet_220_src02.DrawImage.svg");
        }
    }
}

 

Note that drawing a vector image is not supported at now. It needs to convert the drawn vector image to a raster before drawing as shown below:
 
// The following code shows how to draw a vector image on another vector image.
// For example let's draw an Svg image over itself with optional scaling.
 
string dir = "c:\\aspose.work\\IMAGINGNET\\3346\\";
 
using (MemoryStream drawnImageStream = new MemoryStream())
{
    // First, rasterize Svg to Png and write the result to a stream.
    using (SvgImage svgImage = (SvgImage)Image.Load(dir + "asposenet_220_src02.svg"))
    {
        SvgRasterizationOptions rasterizationOptions = new SvgRasterizationOptions();
        rasterizationOptions.PageSize = svgImage.Size;
 
        PngOptions saveOptions = new PngOptions();
        saveOptions.VectorRasterizationOptions = rasterizationOptions;
 
        svgImage.Save(drawnImageStream, saveOptions);
 
        // Now load a Png image from stream for further drawing.
        drawnImageStream.Seek(0, SeekOrigin.Begin);
        using (RasterImage imageToDraw = (RasterImage)Image.Load(drawnImageStream))
        {   
            // Drawing on the existing Svg image.
            Aspose.Imaging.FileFormats.Svg.Graphics.SvgGraphics2D graphics = new Aspose.Imaging.FileFormats.Svg.Graphics.SvgGraphics2D(svgImage);
 
            // Scale down the entire drawn image by 2 times and draw it to the center of the drawing surface.
            int width = imageToDraw.Width / 2;
            int height = imageToDraw.Height / 2;
            Point origin = new Point((svgImage.Width - width) / 2, (svgImage.Height - height) / 2);
            Size size = new Size(width, height);
 
            graphics.DrawImage(imageToDraw, origin, size);
 
            // Save the result image
            using (SvgImage resultImage = graphics.EndRecording())
            {
                resultImage.Save(dir + "asposenet_220_src02.DrawVectorImage.svg");
            }
        }
    }
}

 

▲IMAGINGNET-3356儲存EMF影象檔案時丟擲異常

using (Image image = Image.Load("1.emf"))
{
    image.Save("out.emf");
}

 

▲IMAGINGNET-3347 Aspose.Imaging 19.1.0圖形繪製對PSD檔案沒有影響

string psdFileName = ("asposenet_230_src_psd.psd");
string drwFileName = ("asposenet_230_200psd.psd");
string psdFileNameOutput = ("asposenet_230_output_psd.psd");
 
            using (Aspose.Imaging.Image canvasImagePsd = Aspose.Imaging.Image.Load(psdFileName))
            {
                using (Aspose.Imaging.Image imageToDrawPng = Aspose.Imaging.Image.Load(drwFileName))
                {
                    Aspose.Imaging.Graphics graphics = new Aspose.Imaging.Graphics(canvasImagePsd);
                    Aspose.Imaging.Rectangle signRect = new Aspose.Imaging.Rectangle(0, 0, 200, 200);
                    graphics.DrawImage(imageToDrawPng, new Aspose.Imaging.Point(signRect.X, signRect.Y));
                    canvasImagePsd.Save(psdFileNameOutput);
                }
            }

 

▲IMAGINGNET-3316同步訪問DJVU格式的互斥影象操作

public void TestParallel()
{
    string fileName = "test1.djvu";
    int numThreads = 20;
    var tasks = Enumerable.Range(1, numThreads).Select(
        taskNum =>
            {
                var inputFile = this.GetFileInBaseFolder(fileName);
                var outputFile = this.GetFileInOutputFolder($"{fileName}_task{taskNum}.png");
                return Task.Run(
                    () =>
                        {
                            using (FileStream fs = File.OpenRead(inputFile))
                            {
                                using (Image image = Image.Load(fs))
                                {
                                    image.Save(outputFile, new PngOptions());
                                }
                            }
                        });
            });
    Task.WaitAll(tasks.ToArray());
}

 

▲呼叫FontSettings.Reset方法後,IMAGINGNET-3353 FontsFolder沒有被重置

string sourceFIle = @"grinched-regular-font.psd";
FontSettings.SetFontsFolder(@"c://Font");
FontSettings.UpdateFonts();
 
using (PsdImage image = (PsdImage)Image.Load(sourceFIle, new PsdLoadOptions()))
{
image.Save("result.png", new PngOptions());
}
 
FontSettings.Reset();
FontSettings.UpdateFonts();
 
using (PsdImage image = (PsdImage)Image.Load(sourceFIle, new PsdLoadOptions()))
{
image.Save("result2.png", new PngOptions());
}

 

▲IMAGINGNET-3309 WMF到PNG未正確轉換

using (Image image = Image.Load("importimage2.wmf"))
{
    image.Save(
        "importimage2.png",
        new PngOptions()
            {
                VectorRasterizationOptions = new WmfRasterizationOptions()
                                                 {
                                                     BackgroundColor = Color.WhiteSmoke,
                                                     PageWidth = image.Width,
                                                     PageHeight = image.Height
                                                 }
            });
}

 

▲IMAGINGNET-3395 EMF未正確轉換為SVG

string baseFolder = "D:";
            string fileName = "image7.emf";
            string inputFileName = Path.Combine(baseFolder, fileName);
            string outputFileName = inputFileName + ".svg";
            using (Image image = Image.Load(inputFileName))
            {
                image.Save(outputFileName, new SvgOptions(){VectorRasterizationOptions = new EmfRasterizationOptions(){PageSize = image.Size}});
            }

 

▲IMAGINGNET-3266修復並行DJVU處理並檢查記憶體洩漏

protected string TestDirectory => "Custom";
private readonly List imageSaveData = new List()
{
    new Tuple(new BmpOptions(), ".bmp"),
    new Tuple(new PngOptions(), ".png"),
    new Tuple(new JpegOptions(), ".jpg"),
    new Tuple(new WebPOptions(), ".webp"),
    new Tuple(new GifOptions(), ".gif"),
    new Tuple(new TiffOptions(TiffExpectedFormat.Default), ".tiff"),
    new Tuple(new PsdOptions(), ".psd")
};
 
 public async Task TestDjvuExportParallel()
{
    var tasks = imageSaveData.Select(t => SaveAsAsync("test1.djvu", t.Item1, t.Item2)).ToList();
    tasks.AddRange(imageSaveData.Select(t => SaveAsAsync("test2.djvu", t.Item1, t.Item2)));
    await Task.WhenAll(tasks);
}
 
public void TestDjvuExportOrdered()
{
    foreach(var tuple in imageSaveData)
    {
        this.SaveAs("test1.djvu", false, tuple.Item1, tuple.Item2);
        this.SaveAs("test2.djvu", false, tuple.Item1, tuple.Item2);
    }
}
 
public void TestMultiPageExport()
{
    this.SaveAs("test1.djvu", false, new TiffOptions(TiffExpectedFormat.Default) { MultiPageOptions = new DjvuMultiPageOptions() }, ".tiff");
}
 
private async Task SaveAsAsync(string fileName, ImageOptionsBase optionsBase, string extension)
{
    await Task.Run(() =>
    {
        this.SaveAs(fileName, true, optionsBase, extension);
    });
}
 
private void SaveAs(string fileName, bool parallel, ImageOptionsBase optionsBase, string extension)
{
    using (FileStream fs = File.OpenRead(Path.Combine(this.TestDirectory, fileName)))
    {
        using (var image = Image.Load(fs) as RasterImage)
        {
            image.Save(Path.Combine(this.TestDirectory, $"{fileName}_{ (parallel ? "parallel" : "ordered") }{extension}"),
                optionsBase);
        }
    }
}

 

▲IMAGINGNET-3265修復WebP裁剪操作 - 由於某種原因需要快取

Rectangle rect = new Rectangle(100, 100, 100, 150);
            string baseFolder = "D:";
            string inputFileName = Path.Combine(baseFolder, "test.webp");
            string outputFileName = Path.Combine(baseFolder, "test_out.webp");
            string outputFileNameCached = Path.Combine(baseFolder, "test_out_cache.webp");
 
            //crop & save
            using (RasterImage image = (RasterImage)Image.Load(inputFileName))
            {
                image.Crop(rect);
                image.Save(outputFileName);
            }
 
            //crop & save with cache
            using (RasterImage image = (RasterImage)Image.Load(inputFileName))
            {
                image.CacheData();
                image.Crop(rect);
                image.Save(outputFileNameCached);
            }
               //compare files
            using (FileStream fs = new FileStream(outputFileName, FileMode.Open))
            using (FileStream fs1 = new FileStream(outputFileNameCached, FileMode.Open))
            {
                Assert.AreEqual(fs.Length, fs1.Length, "Length of files not equal");
                for (int i = 0; i < fs.Length; i++)
                {
                    int aByte = fs.ReadByte();
                    int bByte = fs1.ReadByte();
                    if (aByte.CompareTo(bByte) != 0)
                    {
                        throw new Exception("Files not equal");
                    }
                }
            }

   

▲IMAGINGNET-3282在自我更新的情況下修復巨大的WebP動畫RAM消耗

string baseFolder = "D:";
string inputFile = Path.Combine(baseFolder, "Animation1.webp");
string outputFile = Path.Combine(baseFolder, "Animation2.webp");
using (MemoryStream ms = new MemoryStream())
{
  using (WebPImage image = (WebPImage)Image.Load(inputFile))
  {
    image.Resize(300, 450, ResizeType.HighQualityResample);
    image.Crop(new Rectangle(10, 10, 200, 300));
    image.RotateFlipAll(RotateFlipType.Rotate90FlipX);
    image.Save(ms);
  }
 
  using (FileStream fs = new FileStream(outputFile, FileMode.Create))
  {
    fs.Write(ms.GetBuffer(), 0, (int)ms.Length)