//
// 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 });
}
}
}