彩票走势图

图像处理控件Aspose.Imaging v20.6 三大新功能上线!支持APNG(动画PNG)文件格式

原创|产品更新|编辑:李显亮|2020-06-18 10:19:49.870|阅读 226 次

概述:Aspose.Imaging for .NET更新至最新版v20.6,支持APNG(动画PNG)文件格式,支持BMP的新压缩方法DXT1 ,支持批量导出到WebP以获得多页图像,欢迎下载体验。

# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>

Aspose.Imaging for .NET一种高级图像处理控件,允许开发人员创建,编辑,绘制或转换图像。图像导出和转换是API核心功能之一,它允许在不安装Photoshop应用程序或任何其他图像编辑器的情况下保存为AdobePhotoshop®本机格式。

事实证明,Aspose.Imaging是处理各种图像格式的强大API。除单页图像外,Aspose.Imaging还支持处理多页图像,包括GIF,TIFF,PSD,DICOM,CDR和WebP。

近期发布了Aspose.Imaging for .NET v20.6,支持APNG(动画PNG)文件格式,支持BMP的新压缩方法DXT1 ,支持批量导出到WebP以获得多页图像,还没使用过的朋友可以点击下载最新版Aspose.Imaging

新增与改善

key 概述 类别
IMAGINGNET-3618 实现对APNG(动画PNG)文件格式的支持 功能
IMAGINGNET-3849 支持BMP的新压缩方法DXT1 功能
IMAGINGNET-3781 支持批量导出到WebP以获得多页图像 功能
IMAGINGNET-3882 无法从XMP元数据提取Azure标签信息 增强功能
IMAGINGNET-3804 将WMF保存为PNG时形状崩溃 增强功能

新功能用法示例

IMAGINGNET-3618实现对APNG(动画PNG)文件格式的支持

创建图像并设置其像素。

// Example 1. Creating an image and setting its pixels.
using System.Diagnostics;
using Aspose.Imaging;
using Aspose.Imaging.ImageOptions;
using Aspose.Imaging.FileFormats.Png;
using Aspose.Imaging.FileFormats.Apng;

// Load pixels from source raster image
Size imageSize;
int[] imagePixels;
using (RasterImage sourceImage = (RasterImage)Image.Load("not_animated.png"))
{
    imageSize = sourceImage.Size;
    imagePixels = sourceImage.LoadArgb32Pixels(sourceImage.Bounds);
}

// Create APNG image and set its pixels
using (ApngImage image = (ApngImage)Image.Create(
   new ApngOptions()
       {
           Source = new FileCreateSource("created_apng.png", false),
            ColorType = PngColorType.TruecolorWithAlpha
       },
    imageSize.Width,
    imageSize.Height))
{
    image.SaveArgb32Pixels(image.Bounds, imagePixels);
    image.Save();
}

// Check output file format
using (Image image = Image.Load("created_apng.png")) {
    Debug.Assert(image.FileFormat == FileFormat.Apng);
    Debug.Assert(image is ApngImage);
}

栅格图像操作

// The brightness adjustment operation

using Aspose.Imaging;
using Aspose.Imaging.FileFormats.Apng;

using (ApngImage image = (ApngImage)Image.Load("elephant.png"))
{
 image.AdjustBrightness(100);
 image.Save("AdjustBrightness.png");
}

从另一个单页图像创建动画图像

// Create an animated image from another single-page image

using Aspose.Imaging;
using Aspose.Imaging.ImageOptions;
using Aspose.Imaging.FileFormats.Apng;

const int AnimationDuration = 1000; // 1 s
const int FrameDuration = 70; // 70 ms
using (RasterImage sourceImage = (RasterImage)Image.Load("not_animated.png"))
{
   ApngOptions createOptions = new ApngOptions
    {
       Source = new FileCreateSource("raster_animation.png", false),
       DefaultFrameTime = (uint)FrameDuration,
       ColorType = PngColorType.TruecolorWithAlpha,
    };

   using (ApngImage apngImage = (ApngImage)Image.Create(
       createOptions,
       sourceImage.Width,
       sourceImage.Height))
    {
       int numOfFrames = AnimationDuration / FrameDuration;
       int numOfFrames2 = numOfFrames / 2;

       apngImage.RemoveAllFrames();

       // add first frame
       apngImage.AddFrame(sourceImage, FrameDuration);

       // add intermediate frames
       for (int frameIndex = 1; frameIndex < numOfFrames - 1; ++frameIndex) { apngImage.AddFrame(sourceImage, FrameDuration); ApngFrame lastFrame = (ApngFrame)apngImage.Pages[apngImage.PageCount - 1]; float gamma = frameIndex >= numOfFrames2 ? numOfFrames - frameIndex - 1 : frameIndex;
           lastFrame.AdjustGamma(gamma);
        }

       // add last frame
       apngImage.AddFrame(sourceImage, FrameDuration);

       apngImage.Save();
    }
}

根据矢量图形操作创建APNG动画

// Create APNG animation based on vector graphics operations

using Aspose.Imaging;
using Aspose.Imaging.FileFormats.Apng;

// preparing the animation scene
const int SceneWidth = 400; 
const int SceneHeigth = 400;
const uint ActDuration = 1000; // Act duration, in milliseconds
const uint TotalDuration = 4000; // Total duration, in milliseconds
const uint FrameDuration = 50; // Frame duration, in milliseconds
Scene scene = new Scene();

Ellipse ellipse = new Ellipse
                      {
                         FillColor = Color.FromArgb(128, 128, 128),
                         CenterPoint = new PointF(SceneWidth / 2f, SceneHeigth / 2f),
                         RadiusX = 80,
                         RadiusY = 80
                      };
scene.AddObject(ellipse);

Line line = new Line
                {
                   Color = Color.Blue,
                   LineWidth = 10,
                   StartPoint = new PointF(30, 30),
                   EndPoint = new PointF(SceneWidth - 30, 30)
                };
scene.AddObject(line);

IAnimation lineAnimation1 = new LinearAnimation(
                               delegate(float progress)
                                    {
                                       line.StartPoint = new PointF(
                                           30 + (progress * (SceneWidth - 60)),
                                           30 + (progress * (SceneHeigth - 60)));
                                       line.Color = Color.FromArgb(
                                           (int)(progress * 255),
                                           0,
                                           255 - (int)(progress * 255));
                                    }) { Duration = ActDuration };
IAnimation lineAnimation2 = new LinearAnimation(
                               delegate(float progress)
                                    {
                                       line.EndPoint = new PointF(
                                           SceneWidth - 30 - (progress * (SceneWidth - 60)),
                                           30 + (progress * (SceneHeigth - 60)));
                                       line.Color = Color.FromArgb(
                                           255,
                                           (int)(progress * 255),
                                           0);
                                    })
                                { Duration = ActDuration };
IAnimation lineAnimation3 = new LinearAnimation(
                               delegate(float progress)
                                    {
                                       line.StartPoint = new PointF(
                                           SceneWidth - 30 - (progress * (SceneWidth - 60)),
                                           SceneHeigth - 30 - (progress * (SceneHeigth - 60)));
                                       line.Color = Color.FromArgb(
                                           255 - (int)(progress * 255),
                                           255,
                                           0);
                                    })
                                { Duration = ActDuration };
IAnimation lineAnimation4 = new LinearAnimation(
                               delegate(float progress)
                                    {
                                       line.EndPoint = new PointF(
                                           30 + (progress * (SceneWidth - 60)),
                                           SceneHeigth - 30 - (progress * (SceneHeigth - 60)));
                                       line.Color = Color.FromArgb(
                                           0,
                                           255 - (int)(progress * 255),
                                           (int)(progress * 255));
                                    })
                                { Duration = ActDuration };
IAnimation fullLineAnimation = new SequentialAnimation() { lineAnimation1, lineAnimation2, lineAnimation3, lineAnimation4 };
IAnimation ellipseAnimation1 = new LinearAnimation(
                                  delegate(float progress)
                                       {
                                          ellipse.RadiusX += progress * 10;
                                          ellipse.RadiusY += progress * 10;
                                          int compValue = (int)(128 + (progress * 112));
                                          ellipse.FillColor = Color.FromArgb(
                                              compValue,
                                              compValue,
                                              compValue);
                                       })
                                   { Duration = ActDuration };
IAnimation ellipseAnimation2 = new Delay() { Duration = ActDuration };
IAnimation ellipseAnimation3 = new LinearAnimation(
                                  delegate(float progress)
                                       {
                                          ellipse.RadiusX -= progress * 10;
                                          int compValue = (int)(240 - (progress * 224));
                                          ellipse.FillColor = Color.FromArgb(
                                              compValue,
                                              compValue,
                                              compValue);
                                       })
                                   { Duration = ActDuration };
IAnimation ellipseAnimation4 = new LinearAnimation(
                                  delegate(float progress)
                                       {
                                          ellipse.RadiusY -= progress * 10;
                                          int compValue = (int)(16 + (progress * 112));
                                          ellipse.FillColor = Color.FromArgb(
                                              compValue,
                                              compValue,
                                              compValue);
                                       })
                                   { Duration = ActDuration };
IAnimation fullEllipseAnimation = new SequentialAnimation() { ellipseAnimation1, ellipseAnimation2, ellipseAnimation3, ellipseAnimation4 };
scene.Animation = new ParallelAnimation() { fullLineAnimation, fullEllipseAnimation };

// playing the scene on the newly created ApngImage
ApngOptions createOptions = new ApngOptions
                                {
                                   Source = new FileCreateSource("vector_animation.png", false),
                                   ColorType = PngColorType.TruecolorWithAlpha,
                                };

using (ApngImage image = (ApngImage)Image.Create(createOptions, SceneWidth, SceneHeigth))
{
   image.DefaultFrameTime = FrameDuration;
   scene.Play(image, TotalDuration);
   image.Save();
}

/////////////////////////// Scene.cs /////////////////////////////

using System.Collections.Generic;
using Aspose.Imaging.FileFormats.Apng;

using Graphics = Aspose.Imaging.Graphics;

// The graphics scene
public class Scene
{
   private readonly ListgraphicsObjects = new List();

   public IAnimation Animation { get; set; }

   public void AddObject(IGraphicsObject graphicsObject)
    {
       this.graphicsObjects.Add(graphicsObject);
    }

   public void Play(ApngImage animationImage, uint totalDuration)
    {
       uint frameDuration = animationImage.DefaultFrameTime;
       uint numFrames = totalDuration / frameDuration;
       uint totalElapsed = 0;
       for (uint frameIndex = 0; frameIndex < numFrames; frameIndex++) { if (this.Animation != null) { this.Animation.Update(totalElapsed); } ApngFrame frame = animationImage.PageCount == 0 || frameIndex > 0
                                  ? animationImage.AddFrame()
                                  : (ApngFrame)animationImage.Pages[0];
           Graphics graphics = new Graphics(frame);
           graphics.SmoothingMode = SmoothingMode.AntiAlias;
           foreach (IGraphicsObject graphicsObject in this.graphicsObjects)
            {
               graphicsObject.Render(graphics);
            }

           totalElapsed += frameDuration;
        }
    }
}

/////////////////////////// IGraphicsObject.cs /////////////////////////////

using Graphics = Aspose.Imaging.Graphics;

// The graphics object
public interface IGraphicsObject
{
   void Render(Graphics graphics);
}

/////////////////////////// Line.cs /////////////////////////////

using Graphics = Aspose.Imaging.Graphics;

// The line
public class Line : IGraphicsObject
{
   public PointF StartPoint { get; set; }

   public PointF EndPoint { get; set; }

   public float LineWidth { get; set; }

   public Color Color { get; set; }

   public void Render(Graphics graphics)
    {
       graphics.DrawLine(new Pen(this.Color, this.LineWidth), this.StartPoint, this.EndPoint);
    }
}

/////////////////////////// Ellipse.cs /////////////////////////////

using Aspose.Imaging.Brushes;

using Graphics = Aspose.Imaging.Graphics;

// The ellipse
public class Ellipse : IGraphicsObject
{
   public Color FillColor { get; set; }

   public PointF CenterPoint { get; set; }

   public float RadiusX { get; set; }

   public float RadiusY { get; set; }

   public void Render(Graphics graphics)
    {
       graphics.FillEllipse(
           new SolidBrush(this.FillColor),
           this.CenterPoint.X - this.RadiusX,
           this.CenterPoint.Y - this.RadiusY,
           this.RadiusX * 2,
           this.RadiusY * 2);
    }
}

/////////////////////////// IAnimation.cs /////////////////////////////

// The animation
public interface IAnimation
{
// The animation duration, in milliseconds.
   uint Duration { get; set; }

   void Update(uint elapsed);
}

/////////////////////////// LinearAnimation.cs /////////////////////////////

// The linear animation
public class LinearAnimation : IAnimation
{
   private readonly AnimationProgressHandler progressHandler;

   public delegate void AnimationProgressHandler(float progress);

   public LinearAnimation(AnimationProgressHandler progressHandler)
    {
       if (progressHandler == null)
        {
           throw new System.ArgumentNullException("progressHandler");
        }

       this.progressHandler = progressHandler;
    }

   public uint Duration { get; set; }

   public void Update(uint elapsed)
    {
       if (elapsed <= this.Duration) { this.progressHandler.Invoke((float)elapsed / this.Duration); } } } /////////////////////////// Delay.cs ///////////////////////////// // The simple delay between other animations public class Delay : IAnimation { public uint Duration { get; set; } public void Update(uint elapsed) { // nop } } /////////////////////////// ParallelAnimation.cs ///////////////////////////// using System.Collections.Generic; // The parallel animation processor public class ParallelAnimation : List, IAnimation
{
   public uint Duration
    {
       get
        {
           uint maxDuration = 0;
           foreach (IAnimation animation in this)
            {
               if (maxDuration < animation.Duration) { maxDuration = animation.Duration; } } return maxDuration; } set { throw new System.NotSupportedException(); } } public void Update(uint elapsed) { foreach (IAnimation animation in this) { animation.Update(elapsed); } } } /////////////////////////// SequentialAnimation.cs ///////////////////////////// using System.Collections.Generic; // The sequential animation processor public class SequentialAnimation : List, IAnimation
{
   public uint Duration
    {
       get
        {
           uint summDuration = 0;
           foreach (IAnimation animation in this)
            {
               summDuration += animation.Duration;
            }

           return summDuration;
        }

       set
        {
           throw new System.NotSupportedException();
        }
    }

   public void Update(uint elapsed)
    {
       uint totalDuration = 0;
       foreach (IAnimation animation in this)
        {
           if (totalDuration > elapsed)
            {
               break;
            }
           
           animation.Update(elapsed - totalDuration);
           totalDuration += animation.Duration;
        }
    }
}

IMAGINGNET-3781支持批量导出到WebP以获得多页图像

using (TiffImage tiffImage = (TiffImage)Image.Load("10MB_Tif.tif"))
{
   // Set batch operation for pages
   tiffImage.PageExportingAction = delegate(int index, Image page)
         {
            // Fires garbage collection to avoid unnecessary garbage storage from previous pages
            GC.Collect();

            ((RasterImage)page).Rotate(90);
         };

   tiffImage.Save("rotated.webp", new WebPOptions());

   /* Attention! In batch mode all pages will be released in this line!
    If you want to further perform operations on the original image, you should reload it from the source to another instance. */
}

IMAGINGNET-3849-支持针对BMP的新压缩方法DXT1

DXT1压缩

DXTn是一组相关的有损纹理压缩算法。该算法有五种变体(命名为DXT1至DXT5),每种变体均针对特定类型的图像数据而设计。全部将4X4像素块转换为64位或128位量,对于24位RGB输入数据,压缩率为6:1;对于32位RGBA输入数据,压缩率为4:1。它包含在Microsoft的DirectX 6.0和OpenGL 1.3中,导致该技术在硬件和软件制造商中得到广泛采用。

DXT1算法

DXT1(也称为块压缩1或BC1)是最简单的压缩,也是其他类型DXT算法的基础。它是DXT的最小变体,在64位输出中存储16个输入像素,包括两个16位颜色值和一个4X4 2位查找表。颜色信息也以压缩方式存储,因此每种颜色仅使用16位。这意味着纹理的这16个像素仅占用64位(调色板使用32位,索引使用32位)。那是1:8的压缩比。

如何使用DXT1压缩

以下代码演示了如何使用DXT1压缩来压缩现有图像:

using (var image = Image.Load("Tiger.bmp"))
{
    image.Save("CompressedTiger.bmp", new BmpOptions { Compression = BitmapCompression.Dxt1 });
}

如何解压缩图像

以下代码显示了如何解压缩先前压缩的图像:

using (var image = Image.Load("CompressedTiger.bmp"))
{
    image.Save("DecompressedTiger.bmp", new BmpOptions());
}

还想要更多吗?您可以点击阅读
【2019 · Aspose最新资源整合】查找需要的教程资源。如果您有任何疑问或需求,请随时加入Aspose技术交流群(642018183),我们很高兴为您提供查询和咨询

标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn


为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP