public void DuplicateStreamIsCollected() { VerifySupportsExceptionsInDelegates(); var handle = DoWork(); CollectGarbage(); Assert.False(SKObject.GetInstance <SKManagedStream>(handle, out _)); IntPtr DoWork() { var dotnet = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 }); var stream = new SKManagedStream(dotnet, true); Assert.Equal(1, stream.ReadByte()); Assert.Equal(2, stream.ReadByte()); var dupe1 = stream.Duplicate(); Assert.Equal(1, dupe1.ReadByte()); Assert.Equal(2, dupe1.ReadByte()); Assert.Throws <InvalidOperationException>(() => stream.Duplicate()); stream.Dispose(); var dupe2 = dupe1.Duplicate(); Assert.Equal(1, dupe2.ReadByte()); Assert.Equal(2, dupe2.ReadByte()); return(dupe2.Handle); } }
public unsafe void StreamLosesOwnershipAndCanBeDisposedButIsNotActually() { var path = Path.Combine(PathToImages, "color-wheel.png"); var bytes = File.ReadAllBytes(path); var stream = new SKManagedStream(new MemoryStream(bytes), true); var handle = stream.Handle; Assert.True(stream.OwnsHandle); Assert.False(stream.IgnorePublicDispose); Assert.True(SKObject.GetInstance <SKManagedStream>(handle, out _)); var codec = SKCodec.Create(stream); Assert.False(stream.OwnsHandle); Assert.True(stream.IgnorePublicDispose); stream.Dispose(); Assert.True(SKObject.GetInstance <SKManagedStream>(handle, out var inst)); Assert.Same(stream, inst); Assert.Equal(SKCodecResult.Success, codec.GetPixels(out var pixels)); Assert.NotEmpty(pixels); codec.Dispose(); Assert.False(SKObject.GetInstance <SKManagedStream>(handle, out _)); }
public void FullOwnershipIsTransferredToTheChildIfTheParentIsDisposed() { VerifySupportsExceptionsInDelegates(); var dotnet = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 }); var stream = new SKManagedStream(dotnet, true); Assert.Equal(1, stream.ReadByte()); Assert.Equal(2, stream.ReadByte()); var dupe1 = stream.Duplicate(); Assert.Equal(1, dupe1.ReadByte()); Assert.Equal(2, dupe1.ReadByte()); Assert.Throws <InvalidOperationException>(() => stream.Duplicate()); stream.Dispose(); var dupe2 = dupe1.Duplicate(); Assert.Equal(1, dupe2.ReadByte()); Assert.Equal(2, dupe2.ReadByte()); Assert.Throws <InvalidOperationException>(() => dupe1.Duplicate()); dupe1.Dispose(); dupe2.Dispose(); Assert.Throws <ObjectDisposedException>(() => dotnet.Position); }
public void DotNetStreamIsNotCollected() { var dotnet = CreateTestStream(); var stream = new SKManagedStream(dotnet, false); Assert.Equal(0, dotnet.Position); stream.Dispose(); Assert.Equal(0, dotnet.Position); }
public void DotNetStreamIsCollected() { var dotnet = CreateTestStream(); var stream = new SKManagedStream(dotnet, true); Assert.Equal(0, dotnet.Position); stream.Dispose(); Assert.Throws <ObjectDisposedException>(() => dotnet.Position); }
public void Dispose() { Font?.Dispose(); Font = null; FontStream?.Dispose(); FontStream = null; FontSource?.Dispose(); FontSource = null; ImageBitmap?.Dispose(); ImageBitmap = null; ImageData?.Dispose(); ImageData = null; }
public void DotNetStreamIsNotClosedPrematurely() { var dotnet = CreateTestStream(); var stream = new SKManagedStream(dotnet, true); Assert.Equal(0, stream.Position); var dupe = stream.Duplicate(); Assert.Equal(0, dupe.Position); stream.Dispose(); Assert.Equal(0, dupe.Position); dupe.Dispose(); Assert.Throws <ObjectDisposedException>(() => dotnet.Position); }
/// <summary> /// Qrs the decoder. /// </summary> /// <param name="qrCodeFileStream">The qr code file stream.</param> /// <returns>System.String.</returns> /// <exception cref="System.Exception">未识别的图片文件</exception> public static string QRDecoder(Stream qrCodeFileStream) { var sKManagedStream = new SKManagedStream(qrCodeFileStream, true); var sKBitmap = SKBitmap.Decode(sKManagedStream); sKManagedStream.Dispose(); if (sKBitmap.IsEmpty) { sKBitmap.Dispose(); throw new Exception("未识别的图片文件"); } var w = sKBitmap.Width; var h = sKBitmap.Height; var ps = w * h; var bytes = new byte[ps * 3]; var byteIndex = 0; for (var x = 0; x < w; x++) { for (var y = 0; y < h; y++) { var color = sKBitmap.GetPixel(x, y); bytes[byteIndex + 0] = color.Red; bytes[byteIndex + 1] = color.Green; bytes[byteIndex + 2] = color.Blue; byteIndex += 3; } } sKBitmap.Dispose(); var qRCodeReader = new QRCodeReader(); var rGbLuminanceSource = new RGBLuminanceSource(bytes, w, h); var hybridBinarizer = new HybridBinarizer(rGbLuminanceSource); var binaryBitmap = new BinaryBitmap(hybridBinarizer); var hints = new Dictionary <DecodeHintType, object> { { DecodeHintType.CHARACTER_SET, "utf-8" } }; var result = qRCodeReader.decode(binaryBitmap, hints); return(result != null ? result.Text : ""); }
public unsafe void StreamLosesOwnershipToCodecButIsNotForgotten() { var bytes = File.ReadAllBytes(Path.Combine(PathToImages, "color-wheel.png")); var dotnet = new MemoryStream(bytes); var stream = new SKManagedStream(dotnet, true); var handle = stream.Handle; Assert.True(stream.OwnsHandle); Assert.True(SKObject.GetInstance <SKManagedStream>(handle, out _)); var codec = SKCodec.Create(stream); Assert.False(stream.OwnsHandle); stream.Dispose(); Assert.True(SKObject.GetInstance <SKManagedStream>(handle, out _)); Assert.Equal(SKCodecResult.Success, codec.GetPixels(out var pixels)); Assert.NotEmpty(pixels); }
public static Texture2D LoadImageAsTexture(string path) { SKBitmap bitmap; try { FileStream imgStream = File.OpenRead(path); SKManagedStream skManagedStream = new SKManagedStream(imgStream); bitmap = SKBitmap.Decode(skManagedStream); //Guarantee BGRA8888 to the loaded image if (bitmap.ColorType != SKColorType.Bgra8888) { SKBitmap tempBitmap = new SKBitmap(bitmap.Width, bitmap.Height, false); bitmap.CopyTo(tempBitmap, SKColorType.Bgra8888); bitmap.Dispose(); bitmap = tempBitmap; } skManagedStream.Dispose(); imgStream.Close(); imgStream.Dispose(); } catch (Exception ex) { Debug.LogErrorFormat("Could not load file: {0} with error: {1}", Path.GetFileNameWithoutExtension(path), ex.Message); return(null); } if (bitmap == null) //It appears that Skia lib sometimes don't read the image but don't throw a exception. { Debug.LogErrorFormat("Could not load file: {0} the image cannot be opened.", Path.GetFileNameWithoutExtension(path)); return(null); } Texture2D texture; ConvertSKBitmapToTexture2D(bitmap, out texture); texture.name = Path.GetFileNameWithoutExtension(path); return(texture); }
/// <summary> /// Gets the image information. /// </summary> /// <param name="path">The path.</param> /// <returns>Tuple<System.Int32, System.Int32, System.Int64, SkiaSharp.SKEncodedImageFormat>.</returns> /// <exception cref="System.Exception"> /// 路径不能为空 /// or /// 文件不存在 /// or /// 文件过大 /// or /// 文件无效 /// </exception> public static Tuple <int, int, long, SKEncodedImageFormat> GetImageInfo(string path) { if (string.IsNullOrEmpty(path)) { throw new Exception("路径不能为空"); } if (!File.Exists(path)) { throw new Exception("文件不存在"); } var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read); //fileInfo.OpenRead(); var fileLength = fileStream.Length; if (fileLength > maxLength) { fileStream.Dispose(); throw new Exception("文件过大"); } var sKManagedStream = new SKManagedStream(fileStream, true); var sKBitmap = SKBitmap.Decode(sKManagedStream); sKManagedStream.Dispose(); if (sKBitmap.IsEmpty) { sKBitmap.Dispose(); throw new Exception("文件无效"); } var w = sKBitmap.Width; var h = sKBitmap.Height; return(new Tuple <int, int, long, SKEncodedImageFormat>(w, h, fileLength, GetImageFormatByPath(path))); }
public bool ToThumnail(int w = 0, int h = 0) { var output_path = $@"{(new DirectoryInfo(original_file).Parent.Parent.FullName)}\{ImagePath.Thumbs}\"; if (!Directory.Exists(output_path)) { Directory.CreateDirectory(output_path); } using (var input = File.OpenRead(original_file)) { using (var inputStream = new SKManagedStream(input)) { using (var original = SKBitmap.Decode(inputStream)) { int width, height; if (w > 0 || h > 0) { width = w > 0 ? w : size; height = h > 0 ? h : original.Height * width / original.Width; } else { if (original.Width <= size || input.ReadByte() < 2_025) { original.Dispose(); inputStream.Dispose(); input.Dispose(); System.IO.File.Move(original_file, $@"{output_path}\{Path.GetFileName(original_file)}"); return(true); } if (original.Width > original.Height) { width = size; height = original.Height * size / original.Width; } else { width = original.Width * size / original.Height; height = size; } } using (var resized = original.Resize(new SKImageInfo(width, height), SKFilterQuality.High)) { if (resized == null) { return(false); } using (var image = SKImage.FromBitmap(resized)) { using (var output = File.OpenWrite($@"{output_path}\{Path.GetFileName(original_file)}")) { image.Encode(SKEncodedImageFormat.Png, quality).SaveTo(output); } } } } } } return(true); }
/// <summary> /// Images the scaling by oversized. /// </summary> /// <param name="path">The path.</param> /// <param name="maxWidth">The maximum width.</param> /// <param name="maxHeight">The maximum height.</param> /// <param name="quality">The quality.</param> /// <returns>System.Byte[].</returns> public static byte[] ImageScalingByOversized(string path, int maxWidth, int maxHeight, int quality) { byte[] bytes = null; if (!File.Exists(path)) { return(bytes); } var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read); if (fileStream.Length > maxLength) { fileStream.Dispose(); return(bytes); } var sKManagedStream = new SKManagedStream(fileStream, true); var sKBitmap = SKBitmap.Decode(sKManagedStream); sKManagedStream.Dispose(); if (sKBitmap.IsEmpty) { return(bytes); } if (maxWidth < 1) { maxWidth = 1; } if (maxHeight < 1) { maxHeight = 1; } if (quality < 1) { quality = 1; } if (quality > 100) { quality = 100; } var oW = sKBitmap.Width; var oH = sKBitmap.Height; var nW = oW; var nH = oH; if (oW > maxWidth || oH > maxHeight) { nW = maxWidth; nH = maxHeight; double ratio = 1; if (nW > 0 && nH > 0) { ratio = (double)nW / oW; nH = Convert.ToInt32(oH * ratio); if (maxHeight < nH) { ratio = (double)maxHeight / nH; nW = Convert.ToInt32(nW * ratio); nH = maxHeight; } } if (nW < 1 && nH < 1) { nW = oW; nH = oH; } if (nW < 1) { ratio = (double)nH / oH; nW = Convert.ToInt32(oW * ratio); } if (nH < 1) { ratio = (double)nW / oW; nH = Convert.ToInt32(oH * ratio); } var sKBitmap2 = new SKBitmap(nW, nH); var sKCanvas = new SKCanvas(sKBitmap2); var sKPaint = new SKPaint { FilterQuality = SKFilterQuality.Medium, IsAntialias = true }; sKCanvas.DrawBitmap( sKBitmap, new SKRect { Location = new SKPoint { X = 0, Y = 0 }, Size = new SKSize { Height = oH, Width = oW } }, new SKRect { Location = new SKPoint { X = 0, Y = 0 }, Size = new SKSize { Height = nH, Width = nW } }, sKPaint); sKCanvas.Dispose(); sKBitmap.Dispose(); sKBitmap = sKBitmap2; } var sKImage = SKImage.FromBitmap(sKBitmap); sKBitmap.Dispose(); var data = sKImage.Encode(GetImageFormatByPath(path), quality); sKImage.Dispose(); bytes = data.ToArray(); data.Dispose(); return(bytes); }
/// <summary> /// Images the scaling to range. /// </summary> /// <param name="path">The path.</param> /// <param name="maxWidth">The maximum width.</param> /// <param name="maxHeight">The maximum height.</param> /// <param name="quality">The quality.</param> /// <returns>System.Byte[].</returns> public static byte[] ImageScalingToRange(string path, int maxWidth, int maxHeight, int quality) { byte[] bytes = null; if (!File.Exists(path)) { return(bytes); } var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read); //fileInfo.OpenRead(); if (fileStream.Length > maxLength) { fileStream.Dispose(); return(bytes); } var sKManagedStream = new SKManagedStream(fileStream, true); var sKBitmap = SKBitmap.Decode(sKManagedStream); sKManagedStream.Dispose(); if (sKBitmap.IsEmpty) { return(bytes); } if (maxWidth < 1) { maxWidth = 1; } if (maxHeight < 1) { maxHeight = 1; } if (quality < 1) { quality = 1; } if (quality > 100) { quality = 100; } var oW = sKBitmap.Width; var oH = sKBitmap.Height; var nW = oW; var nH = oH; if (nW < maxWidth && nH < maxHeight) //放大 { if (nW < maxWidth) { var r = maxWidth / (double)nW; nW = maxWidth; nH = (int)Math.Floor(nH * r); } if (nH < maxHeight) { var r = maxHeight / (double)nH; nH = maxHeight; nW = (int)Math.Floor(nW * r); } } //限制超出(缩小) if (nW > maxWidth) { var r = maxWidth / (double)nW; nW = maxWidth; nH = (int)Math.Floor(nH * r); } if (nH > maxHeight) { var r = maxHeight / (double)nH; nH = maxHeight; nW = (int)Math.Floor(nW * r); } var sKBitmap2 = new SKBitmap(nW, nH); var sKCanvas = new SKCanvas(sKBitmap2); var sKPaint = new SKPaint { FilterQuality = SKFilterQuality.Medium, IsAntialias = true }; sKCanvas.DrawBitmap( sKBitmap, new SKRect { Location = new SKPoint { X = 0, Y = 0 }, Size = new SKSize { Height = oH, Width = oW } }, new SKRect { Location = new SKPoint { X = 0, Y = 0 }, Size = new SKSize { Height = nH, Width = nW } }, sKPaint); sKCanvas.Dispose(); var sKImage2 = SKImage.FromBitmap(sKBitmap2); sKBitmap2.Dispose(); var data = sKImage2.Encode(GetImageFormatByPath(path), quality); sKImage2.Dispose(); bytes = data.ToArray(); data.Dispose(); return(bytes); }
/// <summary> /// Images the maximum cut by center. /// </summary> /// <param name="path">The path.</param> /// <param name="saveWidth">Width of the save.</param> /// <param name="saveHeight">Height of the save.</param> /// <param name="quality">The quality.</param> /// <returns>System.Byte[].</returns> public static byte[] ImageMaxCutByCenter(string path, int saveWidth, int saveHeight, int quality) { byte[] bytes = null; if (!File.Exists(path)) { return(bytes); } var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read); //fileInfo.OpenRead(); if (fileStream.Length > maxLength) { fileStream.Dispose(); return(bytes); } var sKManagedStream = new SKManagedStream(fileStream, true); var sKBitmap = SKBitmap.Decode(sKManagedStream); sKManagedStream.Dispose(); if (sKBitmap.IsEmpty) { return(bytes); } if (saveWidth < 1) { saveWidth = 1; } if (saveHeight < 1) { saveHeight = 1; } if (quality < 1) { quality = 1; } if (quality > 100) { quality = 100; } var oW = sKBitmap.Width; var oH = sKBitmap.Height; var cutW = saveWidth; var cutH = saveHeight; double ratio = 1; if (cutW > oW) { ratio = oW / (double)cutW; cutH = Convert.ToInt32(cutH * ratio); cutW = oW; if (cutH > oH) { ratio = oH / (double)cutH; cutW = Convert.ToInt32(cutW * ratio); cutH = oH; } } else if (cutW < oW) { ratio = oW / (double)cutW; cutH = Convert.ToInt32(Convert.ToDouble(cutH) * ratio); cutW = oW; if (cutH > oH) { ratio = oH / (double)cutH; cutW = Convert.ToInt32(cutW * ratio); cutH = oH; } } else { if (cutH > oH) { ratio = oH / (double)cutH; cutW = Convert.ToInt32(cutW * ratio); cutH = oH; } } var startX = oW > cutW ? oW / 2 - cutW / 2 : cutW / 2 - oW / 2; var startY = oH > cutH ? oH / 2 - cutH / 2 : cutH / 2 - oH / 2; var sKBitmap2 = new SKBitmap(saveWidth, saveHeight); var sKCanvas = new SKCanvas(sKBitmap2); var sKPaint = new SKPaint { FilterQuality = SKFilterQuality.Medium, IsAntialias = true }; sKCanvas.DrawBitmap( sKBitmap, new SKRect { Location = new SKPoint { X = startX, Y = startY }, Size = new SKSize { Height = cutH, Width = cutW } }, new SKRect { Location = new SKPoint { X = 0, Y = 0 }, Size = new SKSize { Height = saveHeight, Width = saveWidth } }, sKPaint); sKCanvas.Dispose(); var sKImage2 = SKImage.FromBitmap(sKBitmap2); sKBitmap2.Dispose(); var data = sKImage2.Encode(GetImageFormatByPath(path), quality); sKImage2.Dispose(); bytes = data.ToArray(); data.Dispose(); return(bytes); }