// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // namespace ImageProcessor.Formats { using System; using System.IO; using System.Threading.Tasks; using BitMiracle.LibJpeg; /// /// Encoder for writing the data image to a stream in jpeg format. /// public class JpegEncoder : IImageEncoder { /// /// The jpeg quality. /// private int quality = 100; /// /// Gets or sets the quality, that will be used to encode the image. Quality /// index must be between 0 and 100 (compression from max to min). /// /// The quality of the jpg image from 0 to 100. public int Quality { get { return this.quality; } set { this.quality = value.Clamp(1, 100); } } /// public string MimeType => "image/jpeg"; /// /// Gets the default file extension for this encoder. /// /// The default file extension for this encoder. public string Extension => "jpg"; /// /// Indicates if the image encoder supports the specified /// file extension. /// /// The file extension. /// /// true, if the encoder supports the specified /// extensions; otherwise false. /// /// /// is null (Nothing in Visual Basic). /// is a string /// of length zero or contains only blanks. public bool IsSupportedFileExtension(string extension) { Guard.NotNullOrEmpty(extension, "extension"); if (extension.StartsWith(".")) { extension = extension.Substring(1); } return extension.Equals(this.Extension, StringComparison.OrdinalIgnoreCase) || extension.Equals("jpeg", StringComparison.OrdinalIgnoreCase) || extension.Equals("jfif", StringComparison.OrdinalIgnoreCase); } /// /// Encodes the data of the specified image and writes the result to /// the specified stream. /// /// The image, where the data should be get from. /// Cannot be null (Nothing in Visual Basic). /// The stream, where the image data should be written to. /// Cannot be null (Nothing in Visual Basic). /// /// is null (Nothing in Visual Basic). /// - or - /// is null (Nothing in Visual Basic). /// public void Encode(ImageBase image, Stream stream) { Guard.NotNull(image, nameof(image)); Guard.NotNull(stream, nameof(stream)); int pixelWidth = image.Width; int pixelHeight = image.Height; float[] sourcePixels = image.Pixels; SampleRow[] rows = new SampleRow[pixelHeight]; Parallel.For( 0, pixelHeight, y => { byte[] samples = new byte[pixelWidth * 3]; for (int x = 0; x < pixelWidth; x++) { int start = x * 3; int source = ((y * pixelWidth) + x) * 4; samples[start] = (byte)(sourcePixels[source].Clamp(0, 1) * 255); samples[start + 1] = (byte)(sourcePixels[source + 1].Clamp(0, 1) * 255); samples[start + 2] = (byte)(sourcePixels[source + 2].Clamp(0, 1) * 255); } rows[y] = new SampleRow(samples, pixelWidth, 8, 3); }); JpegImage jpg = new JpegImage(rows, Colorspace.RGB); jpg.WriteJpeg(stream, new CompressionParameters { Quality = this.Quality }); } } }