主页 > 互联网  > 

.NETSixLabors.ImageSharpv1.0图像实用程序控制台示例

.NETSixLabors.ImageSharpv1.0图像实用程序控制台示例

使用 C# 控制台应用程序示例在 Windows、Linux 和 MacOS 机器上处理图像,包括创建散点图和直方图,以及根据需要旋转图像以便正确显示。 这个小型实用程序库需要将 NuGet SixLabors.ImageSharp包(版本 1.0.4)添加到.NET Core 3.1/ .NET 6 / .NET 8项目中。它与Windows、Linux和 MacOS兼容。

这已针对ImageSharp v3.0.1 进行了重新设计。

它可以根据百万像素数或长度乘以宽度来调整图像大小,并根据需要保留纵横比。

它根据EXIF数据旋转/翻转图像。这是为了适应移动设备。

它还创建散点图和直方图。

using SixLabors.ImageSharp; using SixLabors.ImageSharp.Metadata.Profiles.Exif; using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Formats.Png; using System.IO; using System; using SixLabors.ImageSharp.Formats.Jpeg;

namespace ImageUtil {     public class GetSize     {         public GetSize(Stream stream)         {             using (Image iOriginal = Image.Load(stream))             {                 stream.Position = 0;                 Width = iOriginal.Width;                 Height = iOriginal.Height;             }         }

        /// <summary>         /// The width of the image specified in the class constructor's Stream parameter         /// </summary>         public int Width { get; }

        /// <summary>         /// The height of the image specified in the class constructor's Stream parameter         /// </summary>         public int Height { get; }     }

    public static class Resize     {         /// <summary>         /// Resize and save an image to a Stream specifying its new width and height         /// </summary>         public static void SaveImage(Stream imageStream, int newWidth, int newHeight, bool preserveImageRatio, Stream saveToStream, int jpegQuality = 100)         {             using (Image iOriginal = Image.Load(imageStream))             {                 imageStream.Position = 0;                 if (preserveImageRatio)                 {                     float percentWidth = newWidth / (float)iOriginal.Width;                     float percentHeight = newHeight / (float)iOriginal.Height;                     float percent = percentHeight < percentWidth ? percentHeight : percentWidth;                     newWidth = (int)Math.Round(iOriginal.Width * percent, 0);                     newHeight = (int)Math.Round(iOriginal.Height * percent, 0);                 }                 resize(imageStream, iOriginal, newWidth, newHeight, saveToStream, jpegQuality);             }         }

        /// <summary>         /// Resize and save an image to a Stream specifying the number of pixels to resize to         /// </summary>         public static void SaveImage(Stream imageStream, int newNumberOfPixels, Stream saveToStream, int jpegQuality = 100)         {             using (Image iOriginal = Image.Load(imageStream))             {                 imageStream.Position = 0;                 double ratio = Math.Sqrt(newNumberOfPixels / (double)(iOriginal.Width * iOriginal.Height));                 resize(imageStream, iOriginal, (int)Math.Round(iOriginal.Width * ratio, 0), (int)Math.Round(iOriginal.Height * ratio, 0), saveToStream, jpegQuality);             }         }

        private static void resize(Stream origSource, Image image, int newWidth, int newHeight, Stream saveTo, int jpegQuality)         {             image.Mutate(x => x.Resize(newWidth, newHeight));             transformImage(image); // NOTE: transform image AFTER resizing it!!!             var format = Image.DetectFormat(origSource);             if (format.Name.ToLower() == "jpeg")             {                 var encoder = new JpegEncoder();                 encoder.Quality = jpegQuality;                 image.SaveAsJpeg(saveTo, encoder);             }             else                 image.Save(saveTo, format);         }         private static void transformImage(Image image)         {             IExifValue exifOrientation = image.Metadata?.ExifProfile?.GetValue(ExifTag.Orientation);

            if (exifOrientation == null)                 return;

            RotateMode rotateMode;             FlipMode flipMode;             setRotateFlipMode(exifOrientation, out rotateMode, out flipMode);

            image.Mutate(x => x.RotateFlip(rotateMode, flipMode));             image.Metadata.ExifProfile.SetValue(ExifTag.Orientation, (ushort)1);         }         private static void setRotateFlipMode(IExifValue exifOrientation, out RotateMode rotateMode, out FlipMode flipMode)         {             var orientation = (ushort)exifOrientation.GetValue();

            switch (orientation)             {                 case 2:                     rotateMode = RotateMode.None;                     flipMode = FlipMode.Horizontal;                     break;                 case 3:                     rotateMode = RotateMode.Rotate180;                     flipMode = FlipMode.None;                     break;                 case 4:                     rotateMode = RotateMode.Rotate180;                     flipMode = FlipMode.Horizontal;                     break;                 case 5:                     rotateMode = RotateMode.Rotate90;                     flipMode = FlipMode.Horizontal;                     break;                 case 6:                     rotateMode = RotateMode.Rotate90;                     flipMode = FlipMode.None;                     break;                 case 7:                     rotateMode = RotateMode.Rotate90;                     flipMode = FlipMode.Vertical;                     break;                 case 8:                     rotateMode = RotateMode.Rotate270;                     flipMode = FlipMode.None;                     break;                 default:                     rotateMode = RotateMode.None;                     flipMode = FlipMode.None;                     break;             }         }     }

    /* CREATE A SCATTER PLOT JPEG/PNG IMAGE */     public static class ScatterPlot     {         static readonly Rgba32 WHITE = new Rgba32(255, 255, 255);         static readonly Rgba32 BLACK = new Rgba32(0, 0, 0);         static readonly Rgba32 RED = new Rgba32(255, 0, 0);         static readonly Rgba32 BLUE = new Rgba32(0, 0, 255);         static readonly Rgba32 GREEN = new Rgba32(0, 192, 0);         static readonly Rgba32 PURPLE = new Rgba32(128, 0, 128);         static readonly Rgba32 ORANGE = new Rgba32(255, 164, 0);         static readonly Rgba32 YELLOW = new Rgba32(255, 225, 0);         static readonly Rgba32 MAGENTA = new Rgba32(255, 0, 255);         static readonly Rgba32 AQUA = new Rgba32(0, 225, 255);         static readonly Rgba32 BLUEJEAN = new Rgba32(0, 128, 255);         static readonly Rgba32 BROWN = new Rgba32(150, 75, 50);         static readonly Rgba32 CHARTREUSE = new Rgba32(223, 255, 0);         static readonly Rgba32 DODGERBLUE = new Rgba32(30, 144, 255);         static readonly Rgba32 NAVY = new Rgba32(0, 0, 128);         static readonly Rgba32 DARKRED = new Rgba32(139, 0, 0);         static readonly Rgba32[] colors = new Rgba32[] { WHITE, BLACK, RED, BLUE, GREEN, PURPLE, ORANGE, YELLOW, MAGENTA, AQUA, BLUEJEAN, BROWN, DODGERBLUE, CHARTREUSE, NAVY, DARKRED };         public static void CreateJPEG(Stream stream, ScatterPlotColors backgroundColor, IEnumerable<PlotPoint> points, int width, int height, int pointSize, int jpegQuality = 100)         {             using (var bmp = new Image<Rgba32>(width / pointSize + 6, height / pointSize + 6, colors[(int)backgroundColor]))                 create(stream, width, height, bmp, points, pointSize, new JpegEncoder() { Quality = jpegQuality });         }         public static void CreateJPEG(string filename, ScatterPlotColors backgroundColor, IEnumerable<PlotPoint> points, int width, int height, int pointSize, int jpegQuality = 100)         {             using (var stream = File.Create(filename))                 CreateJPEG(stream, backgroundColor, points, width, height, pointSize, jpegQuality);         }

        public static void CreatePNG(Stream stream, IEnumerable<PlotPoint> points, int width, int height, int pointSize)         {             using (var bmp = new Image<Rgba32>(width / pointSize + 6, height / pointSize + 6))                 create(stream, width, height, bmp, points, pointSize, new PngEncoder());         }         public static void CreatePNG(string filename, IEnumerable<PlotPoint> points, int width, int height, int pointSize)         {             using (var stream = File.Create(filename))                 CreatePNG(stream, points, width, height, pointSize);         }

        private static double normalize(float min, float max, float value)         {             double x = max - min;             if(x == 0)                 return 0;             return (value - min) / x;         }

        private static void create(Stream stream, int width, int height, Image<Rgba32> bmp, IEnumerable<PlotPoint> points, int pointSize, SixLabors.ImageSharp.Formats.IImageEncoder imageEncoder)         {             float xMax = float.MinValue, xMin = float.MaxValue, yMax = float.MinValue, yMin = float.MaxValue;             foreach (var pt in points)             {                 xMax = Math.Max(pt.x, xMax);                 xMin = Math.Min(pt.x, xMin);                 yMax = Math.Max(pt.y, yMax);                 yMin = Math.Min(pt.y, yMin);             }             float xDelta = Math.Max(1, xMax - xMin), yDelta = Math.Max(1, yMax - yMin);             int w = width / pointSize;             int h = height / pointSize;             foreach (var pt in points)             {                 int x = (int)(w * normalize(xMin, xMax, pt.x));                 int y = (int)(h * normalize(yMin, yMax, pt.y));                 bmp[x + 3, y + 3] = colors[((int)pt.color) % colors.Length];             }             bmp.Mutate(x => x.Flip(FlipMode.Vertical));             bmp.Mutate(x => x.Resize(width, height));             bmp.Save(stream, imageEncoder);         }     }     public class PlotPoint     {         public ScatterPlotColors color { get; }         public float x { get; }         public float y { get; }         public PlotPoint(float x, float y, ScatterPlotColors color)         {             this.x = x;             this.y = y;             this.color = color;         }     }     public enum ScatterPlotColors     {         WHITE,         BLACK,         RED,         BLUE,         GREEN,         PURPLE,         ORANGE,         YELLOW,         MAGENTA,         AQUA,         BLUEJEAN,         BROWN,         CHARTREUSE,         DODGERBLUE,         NAVY,         DARKRED     }

    /* CREATE A PNG HISTOGRAM OF AN IMAGE */     public static class Histogram     {         /// <summary>         /// Create a histogram from the data in a stream         /// </summary>         public static MemoryStream CreatePNG(Stream stream, int width, int height, LRGB lrgb, byte alphaChannel = 128, bool clipBlackAndWhite = true, byte luminanceShade = 255)         {             using (var bmp = Image<Rgb24>.Load(stream))             {                 return create(bmp, width, height, lrgb, alphaChannel, clipBlackAndWhite, luminanceShade);             }         }

        /// <summary>         /// Create a histogram from the data in a file         /// </summary>         public static MemoryStream CreatePNG(string filename, int width, int height, LRGB lrgb, byte alphaChannel = 128, bool clipBlackAndWhite = true, byte luminanceShade = 255)         {             using (var bmp = Image<Rgb24>.Load(filename))             {                 return create(bmp, width, height, lrgb, alphaChannel, clipBlackAndWhite, luminanceShade);             }         }

        private static MemoryStream create(Image bmp, int width, int height, LRGB lrgb, byte alpha, bool clip, byte shade)         {             ulong[] lumin = new ulong[256];             ulong[] red = new ulong[256];             ulong[] green = new ulong[256];             ulong[] blue = new ulong[256];             var bred = (lrgb & LRGB.RED) != 0;             var bgreen = (lrgb & LRGB.GREEN) != 0;             var bblue = (lrgb & LRGB.BLUE) != 0;             var blumin = (lrgb == LRGB.LUMINANCE);             int w = bmp.Width;             int h = bmp.Height;             var bmp2 = bmp.CloneAs<Rgb24>();             for (int y = 0; y < h; y++)             {                 Span<Rgb24> pixelRow = bmp2.GetPixelRowSpan(y);                 for (int x = 0; x < w; x++)                 {                     var c = pixelRow[x];                     lumin[(int)Math.Round((c.R + c.G + c.B) / 3.0)]++;                     red[c.R]++;                     green[c.G]++;                     blue[c.B]++;                 }             }             ulong max = 0;             int a = (clip ? 1 : 0), b = (clip ? 255 : 256);             for (int i = a; i < b; i++)             {                 if (!blumin)                 {                     if (bred)                         if (max < red[i])                             max = red[i];                     if (bgreen)                         if (max < green[i])                             max = green[i];                     if (bblue)                         if (max < blue[i])                             max = blue[i];                 }                 else if (max < lumin[i])                     max = lumin[i];             }             double HEIGHTFACTOR = 256.0 / max;             if (blumin)             {                 using (var bmplum = new Image<Rgba32>(256, 256))                 {                     var penlum = new VerticalPen(new Rgba32(shade, shade, shade, alpha));                     for (int i = 0; i < 256; i++)                         penlum.Draw(bmplum, i, (int)(lumin[i] * HEIGHTFACTOR));                     bmplum.Mutate(x => x.Resize(width, height));                     MemoryStream ms = new MemoryStream();                     bmplum.Save(ms, new PngEncoder());                     return ms;                 }             }             else             {                 using (var bmppre = new Image<Rgba32>(256, 256))                 {                     Image<Rgba32>? bmpred = null, bmpgreen = null, bmpblue = null;                     VerticalPen? penred = null, pengreen = null, penblue = null;                     if (bred)                     {                         bmpred = new Image<Rgba32>(256, 256);                         penred = new VerticalPen(new Rgba32(255, 0, 0, alpha));                     }                     if (bgreen)                     {                         bmpgreen = new Image<Rgba32>(256, 256);                         pengreen = new VerticalPen(new Rgba32(0, 255, 0, alpha));                     }                     if (bblue)                     {                         bmpblue = new Image<Rgba32>(256, 256);                         penblue = new VerticalPen(new Rgba32(0, 0, 255, alpha));                     }

                    for (int i = 0; i < 256; i++)                     {                         if (bred)                             penred.Draw(bmpred, i, (int)(red[i] * HEIGHTFACTOR));                         if (bgreen)                             pengreen.Draw(bmpgreen, i, (int)(green[i] * HEIGHTFACTOR));                         if (bblue)                             penblue.Draw(bmpblue, i, (int)(blue[i] * HEIGHTFACTOR));                     }

                    if (bred)                     {                         bmppre.Mutate(x => x.DrawImage(bmpred, 1));                         bmpred.Dispose();                     }                     if (bgreen)                     {                         bmppre.Mutate(x => x.DrawImage(bmpgreen, 1));                         bmpgreen.Dispose();                     }                     if (bblue)                     {                         bmppre.Mutate(x => x.DrawImage(bmpblue, 1));                         bmpblue.Dispose();                     }                     bmppre.Mutate(x => x.Resize(width, height));                     MemoryStream ms = new MemoryStream();                     bmppre.Save(ms, new PngEncoder());                     return ms;                 }             }         }         internal class VerticalPen         {             private readonly Rgba32 color;             public VerticalPen(Rgba32 color)             {                 this.color = color;             }             public void Draw(Image<Rgba32> bmp, int row, int height)             {                 if (height <= bmp.Height)                     for (int y = height - 1; y >= 0; y--)                         bmp[row, bmp.Height - 1 - y] = color;             }         }         public enum LRGB         {             LUMINANCE = 0,             RED = 1,             GREEN = 2,             BLUE = 4,             REDBLUE = 1 | 4,             REDGREEN = 1 | 2,             BLUEGREEN = 2 | 4,             REDGREENBLUE = 1 | 2 | 4         }     } }

示例用法 另请参阅:Web 应用程序示例 namespace ConsoleApp1 {     class Program     {         static void Main(string[] args)         {             if(args.Length > 0)             {                 using (var openfs = System.IO.File.OpenRead(args[0]))                 {                     // NOTE: GET IMAGE SIZE                     var size = new ImageUtil.GetSize(openfs);

                    System.Console.WriteLine("IMAGE SIZE: " + size.Width + " x " + size.Height);

                    if (args.Length > 1)                     {                         if (System.IO.File.Exists(args[1]))                             System.IO.File.Delete(args[1]);                         using (var savefs = System.IO.File.OpenWrite(args[1]))                         {                             System.Console.WriteLine("RESIZING IMAGE TO 10K PIXEL THUMBNAIL");

                            // NOTE: RESIZE IMAGE TO 10K PIXELS; THIS WILL ALSO FLIP AND ROTATE IMAGE AS NEEDED                             ImageUtil.Resize.SaveImage(openfs, 10000, savefs);                         }                     }                 }

                System.Console.WriteLine("CREATING LUMINANCE HISTOGRAM: histogram.png");

                // NOTE: CREATE HISTOGRAM WHICH IS RETURNED AS A MEMORY STREAM OF A PORTABLE NETWORK GRAPHICS (PNG) IMAGE FILE                 using (var histogram = ImageUtil.Histogram.CreatePNG(args[0], 300, 150, ImageUtil.Histogram.LRGB.LUMINANCE, 128))                 {                     if (System.IO.File.Exists("histogram.png"))                         System.IO.File.Delete("histogram.png");                     System.IO.File.WriteAllBytes("histogram.png", histogram.ToArray());                 }             }             else                 System.Console.WriteLine("argument one is path to image, argument two [optional] is path to resized image");         }     } }

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。 

标签:

.NETSixLabors.ImageSharpv1.0图像实用程序控制台示例由讯客互联互联网栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“.NETSixLabors.ImageSharpv1.0图像实用程序控制台示例