This can be achieved quite simply using .NET's library for images, but I've still not found out a way to do this via SkiaSharp.
Could you please give me some pointers?
The best way would be to make use of the SKCodec class: https://docs.microsoft.com/dotnet/api/skiasharp.skcodec
You could try try creating it with this: https://docs.microsoft.com/en-us/dotnet/api/skiasharp.skcodec.create?view=skiasharp-1.68.1#SkiaSharp_SKCodec_Create_System_IO_Stream_SkiaSharp_SKCodecResult__
That would mean that the image appears correct.
using var codec = SKCodec.Create(<stream>, out var result);
if (codec == null || result != SKCodecResult.Success)
throw new Exception("bad image.");
Another way would be to just use the SKImage.FromEncodedData and see if there is an image: https://docs.microsoft.com/en-us/dotnet/api/skiasharp.skimage.fromencodeddata?view=skiasharp-1.68.1
Basically this:
using var image = SKImage.FromEncodedData(<stream>);
if (image == null)
throw new Exception("bad image.");
This is a bit heavier as it actually loads the image.
Thank you @mattleibow!
@mattleibow just one quick question if I may, if our image comes in a byte[] format, I can't actually use the SKCodec.Create method. Should I copy the array to a stream, or would that make the operation as slow as its alternatives? (SKImage.FromEncodedData/SKBitmap.Decode)
EDIT: I basically want to check if the image is valid, so that then I can proceed to manipulate it. In that case, it shouldn't be a problem to rely on SKImage.FromEncodedData/SKBitmap.Decode returning a null object, right?
Oh, yeah. I see there is no overload for byte[]. I'll add that.
But, for now, you could even use SKBitmap.DecodeBounds. That also just does the reading of the header so as not to fully decode the entire image. If you want to make sure that it truly is a valid image (not corrupted), then using SKImage.FromEncodedData/SKBitmap.Decode to fully decode is probably the best.
But, as a separate thing, you can also create a SKData from any array:
```csharp
byte[] bytes = ...;
fixed (void* ptr = bytes) {
using var data = SKData.Create((IntPtr)ptr, bytes.length);
}
````
Just remember, the data cannot outlive the fixed block as it requires that the GC does not move/collect the array.