| File: PlatformImage.cs | Web Access |
| Project: src\src\Graphics\src\Graphics\Graphics.csproj (Microsoft.Maui.Graphics) |
using System; using System.IO; using System.Threading.Tasks; namespace Microsoft.Maui.Graphics.Platform { #if NETSTANDARD || NETSTANDARD2_0 || NETSTANDARD2_1 || (NET6_0_OR_GREATER && !PLATFORM) || TIZEN || TIZEN40 public class PlatformImage : IImage { private readonly byte[] _bytes; private readonly int _width; private readonly int _height; private readonly ImageFormat _originalFormat; public PlatformImage(byte[] bytes, ImageFormat originalFormat = ImageFormat.Png) { _bytes = bytes; _originalFormat = originalFormat; if (originalFormat == ImageFormat.Jpeg) { GetJpegDimension(out _width, out _height); } else { GetPngDimension(out _width, out _height); } } public byte[] Bytes => _bytes; public IImage Downsize(float maxWidthOrHeight, bool disposeOriginal = false) { throw new PlatformNotSupportedException(); } public IImage Downsize(float maxWidth, float maxHeight, bool disposeOriginal = false) { throw new PlatformNotSupportedException(); } public IImage Resize(float width, float height, ResizeMode resizeMode = ResizeMode.Fit, bool disposeOriginal = false) { throw new PlatformNotSupportedException(); } /// <summary> /// Saves the contents of this image to the provided <see cref="Stream"/> object. /// </summary> /// <param name="stream">The destination stream the bytes of this image will be saved to.</param> /// <param name="format">The destination format of the image.</param> /// <param name="quality">The destination quality of the image.</param> /// <exception cref="ArgumentOutOfRangeException">Thrown when <paramref name="quality"/> is less than 0 or more than 1.</exception> /// <exception cref="NotImplementedException">Thrown when the provided value in <paramref name="format"/> does not match with the original format for this image.</exception> /// <remarks>The <paramref name="quality"/> value is currently unused.</remarks> public void Save(Stream stream, ImageFormat format = ImageFormat.Png, float quality = 1) { if (quality < 0 || quality > 1) throw new ArgumentOutOfRangeException(nameof(quality), "quality must be in the range of 0..1"); if (format == _originalFormat) { stream.Write(_bytes, 0, _bytes.Length); } else { throw new NotImplementedException(); } } /// <inheritdoc cref="Save"/> public Task SaveAsync(Stream stream, ImageFormat format = ImageFormat.Png, float quality = 1) { if (quality < 0 || quality > 1) throw new ArgumentOutOfRangeException(nameof(quality), "quality must be in the range of 0..1"); if (format == _originalFormat) { Save(stream, format, quality); return Task.FromResult(true); } throw new NotImplementedException(); } public void Dispose() { // Do nothing } public float Width => _width; public float Height => _height; private void GetPngDimension(out int width, out int height) { width = 0; height = 0; // Look into the byte array and get the size of the image for (int i = 0; i <= 3; i++) { width = _bytes[i] | width << 8; height = _bytes[i + 4] | height << 8; } } private void GetJpegDimension(out int width, out int height) { width = 0; height = 0; bool found = false; bool eof = false; var stream = new MemoryStream(_bytes); var reader = new BinaryReader(stream); while (!found || eof) { // read 0xFF and the type reader.ReadByte(); byte type = reader.ReadByte(); // get length int len; switch (type) { // start and end of the image case 0xD8: case 0xD9: len = 0; break; // restart interval case 0xDD: len = 2; break; // the next two bytes is the length default: int lenHi = reader.ReadByte(); int lenLo = reader.ReadByte(); len = (lenHi << 8 | lenLo) - 2; break; } // EOF? if (type == 0xD9) eof = true; // process the data if (len > 0) { // read the data byte[] data = reader.ReadBytes(len); // this is what we are looking for if (type == 0xC0) { width = data[1] << 8 | data[2]; height = data[3] << 8 | data[4]; found = true; } } } reader.Dispose(); stream.Dispose(); } public void Draw(ICanvas canvas, RectF dirtyRect) { throw new PlatformNotSupportedException(); } public static IImage FromStream(Stream stream, ImageFormat format = ImageFormat.Png) { using (var memoryStream = new MemoryStream()) { using (stream) { stream.CopyTo(memoryStream); } return new PlatformImage(memoryStream.ToArray(), format); } } public IImage ToPlatformImage() => this; } #endif }