Skip to content

Comments

Update SkiaSharp from 2.88.8 to 3.119.2#7582

Open
Copilot wants to merge 4 commits intomainfrom
copilot/update-skiasharp-version
Open

Update SkiaSharp from 2.88.8 to 3.119.2#7582
Copilot wants to merge 4 commits intomainfrom
copilot/update-skiasharp-version

Conversation

Copy link
Contributor

Copilot AI commented Feb 18, 2026

  • Update SkiaSharp version from 2.88.8 to 3.119.2 in eng/Versions.props
  • Update MLImage.cs to fix breaking API changes:
    • Replace _image.GetPixelSpan() with GetPixels() pointer-based span with IntPtr.Zero validation
    • Replace SKFilterQuality.None with new SKSamplingOptions(SKFilterMode.Nearest) in ResizeFull()
    • Replace SKPaint.FilterQuality = SKFilterQuality.High with DrawImage + SKSamplingOptions(SKCubicResampler.Mitchell) in ResizeWithPadding() and ResizeWithCrop()
    • Remove obsolete SKPaint.FilterQuality from CloneWithGrayscale()
  • Add explicit SkiaSharp package reference in csproj (no longer transitively pulled by native assets in 3.x)
  • Fix csproj comment to accurately describe the SkiaSharp package references
  • Build the ImageAnalytics project to verify compilation ✅
Original prompt

This section details on the original issue you should resolve

<issue_title>Update to latest version of SkiaSharp</issue_title>
<issue_description>System Information (please complete the following information):

  • OS & Version: Windows 10
  • ML.NET Version: ML.NET v4.0.2
  • .NET Version: .NET 8.0

Describe the bug

In https://github.com/dotnet/machinelearning-samples, open ObjectDetection project, explicitly depend on SkiaSharp package 3.116.1, run, and observe failure:

=====Identify the objects in the images=====

System.InvalidOperationException: Splitter/consolidator worker encountered exception while consuming source data
 ---> System.MissingMethodException: Method not found: 'System.ReadOnlySpan`1<Byte> SkiaSharp.SKBitmap.GetPixelSpan()'.
   at Microsoft.ML.Data.MLImage.get_Pixels()
   at Microsoft.ML.Transforms.Image.ImagePixelExtractingTransformer.Mapper.<>c__DisplayClass5_0`1.<GetGetterCore>b__1(VBuffer`1& dst)
   at Microsoft.ML.Transforms.Onnx.OnnxTransformer.Mapper.NamedOnnxValueGetterVec`1.GetNamedOnnxValueCore()
   at Microsoft.ML.Transforms.Onnx.OnnxTransformer.Mapper.NamedOnnxValueGetterVec`1.GetNamedOnnxValueKnownSize()
   at Microsoft.ML.Transforms.Onnx.OnnxTransformer.Mapper.NamedOnnxValueGetterVec`1.GetNamedOnnxValue()
   at Microsoft.ML.Transforms.Onnx.OnnxTransformer.Mapper.UpdateCacheIfNeeded(Int64 position, INamedOnnxValueGetter[] srcNamedOnnxValueGetters, List`1 activeOutputColNames, OnnxRuntimeOutputCacher outputCache)
   at Microsoft.ML.Transforms.Onnx.OnnxTransformer.Mapper.<>c__DisplayClass14_0`1.<MakeTensorGetter>b__0(VBuffer`1& dst)
   at Microsoft.ML.Data.DataViewUtils.Splitter.InPipe.Impl`1.Fill()
   at Microsoft.ML.Data.DataViewUtils.Splitter.<>c__DisplayClass7_1.<ConsolidateCore>b__2()
   --- End of inner exception stack trace ---
   at Microsoft.ML.Data.DataViewUtils.Splitter.Batch.SetAll(OutPipe[] pipes)
   at Microsoft.ML.Data.DataViewUtils.Splitter.Cursor.MoveNextCore()
   at Microsoft.ML.Data.RootCursorBase.MoveNext()
   at Microsoft.ML.Data.ColumnCursorExtensions.GetColumnArrayDirect[T](IDataView data, Int32 col)+MoveNext()
   at System.Linq.Enumerable.SelectEnumerableIterator`2.MoveNext()
   at System.Linq.Enumerable.TryGetElement[TSource](IEnumerable`1 source, Int32 index, TSource& element)
   at System.Linq.Enumerable.ElementAt[TSource](IEnumerable`1 source, Int32 index)
   at ObjectDection.Program.Main(String[] args) in C:\Projects\Intermediate\machinelearning-samples\samples\csharp\getting-started\DeepLearning_ObjectDetection_Onnx\ObjectDetectionConsoleApp\Program.cs:line 43
========= End of Process..Hit any Key ========

Root cause is ImageAnalytics.

To Reproduce
Steps to reproduce the behavior:

  1. Download and use https://github.com/dotnet/machinelearning-samples
  2. Open samples\csharp\getting-started\DeepLearning_ObjectDetection_Onnx\ObjectDetectionConsoleApp.ObjectDetection.csproj
  3. Use NuGet to explicitly install SkiaSharp version 3.116.1
  4. Run
  5. Fail

Expected behavior

Shouldn't fail or are there alternatively/ways to configure?
Also the package dependency of ML.Net.ImageAnalytics claims SkiaSharp >2.88

Screenshots, Code, Sample Projects
See log error above.

Additional context
I am using ML.Net in a project that already depends on SkiaSharp explicitly.
</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI changed the title [WIP] Update to latest version of SkiaSharp Update SkiaSharp from 2.88.8 to 3.119.2 Feb 18, 2026
@stephentoub stephentoub marked this pull request as ready for review February 23, 2026 03:02
Copilot AI review requested due to automatic review settings February 23, 2026 03:02
@stephentoub stephentoub enabled auto-merge (squash) February 23, 2026 03:03
@stephentoub stephentoub requested a review from ericstj February 23, 2026 03:03
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates Microsoft.ML.ImageAnalytics to be compatible with SkiaSharp 3.x to prevent runtime MissingMethodException when users bring newer SkiaSharp versions into their apps.

Changes:

  • Bumps SkiaSharp to 3.119.2 via eng/Versions.props.
  • Adds an explicit SkiaSharp package reference to Microsoft.ML.ImageAnalytics.csproj.
  • Migrates removed/obsolete APIs in MLImage (replaces GetPixelSpan() with GetPixels() pointer span; replaces SKFilterQuality with SKSamplingOptions / DrawImage).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/Microsoft.ML.ImageAnalytics/Microsoft.ML.ImageAnalytics.csproj Adds explicit managed SkiaSharp reference (3.x no longer comes transitively via native assets).
src/Microsoft.ML.ImageAnalytics/MLImage.cs Updates pixel access and resize/grayscale code paths to SkiaSharp 3.x APIs.
eng/Versions.props Bumps SkiaSharpVersion to 3.119.2.
Comments suppressed due to low confidence (1)

src/Microsoft.ML.ImageAnalytics/MLImage.cs:397

  • Same as above: SKImage.FromBitmap(_image) in the crop path adds an extra allocation/native resource per resize. Prefer drawing from SKBitmap directly with SKSamplingOptions if the SkiaSharp 3.x API supports it, to reduce per-image overhead in pipelines.
            using SKCanvas canvas = new SKCanvas(dst);
            using SKImage image = SKImage.FromBitmap(_image);

            canvas.DrawImage(image, srcRect, destRect, new SKSamplingOptions(SKCubicResampler.Mitchell));


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


<PackageReference Include="SkiaSharp" />

<!-- SkiaSharp reference Windows, UWP, and MacOS native dependencies packages. No need to explicity reference it here. -->
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment above the native assets reference is now inaccurate: this project explicitly references the managed SkiaSharp package, so “No need to explicitly reference it here” (and the current spelling “explicity”) should be updated to avoid confusing future maintainers.

Suggested change
<!-- SkiaSharp reference Windows, UWP, and MacOS native dependencies packages. No need to explicity reference it here. -->
<!-- SkiaSharp already includes Windows, UWP, and macOS native dependency packages; only the Linux native assets package needs to be referenced explicitly here. -->

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 00d95ab — updated the comment to accurately describe that SkiaSharp includes Windows/UWP/macOS native assets, and only Linux needs explicit reference.

Debug.Assert(_image.Info.BytesPerPixel == 4);

return _image.GetPixelSpan();
return new ReadOnlySpan<byte>(_image.GetPixels().ToPointer(), _image.ByteCount);
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pixels creates a span directly from _image.GetPixels() without verifying the pointer is non-zero. If GetPixels() returns IntPtr.Zero (e.g., an unallocated/failed bitmap), the returned span will reference invalid memory. Consider validating the pointer (and expected length) and throwing a clear InvalidOperationException if pixels are unavailable.

Suggested change
return new ReadOnlySpan<byte>(_image.GetPixels().ToPointer(), _image.ByteCount);
var pixelsPtr = _image.GetPixels();
if (pixelsPtr == IntPtr.Zero || _image.ByteCount <= 0)
throw new InvalidOperationException("Pixel data is unavailable.");
return new ReadOnlySpan<byte>(pixelsPtr.ToPointer(), _image.ByteCount);

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added IntPtr.Zero and ByteCount validation in 00d95ab.

Comment on lines 336 to 340
using SKCanvas canvas = new SKCanvas(destBitmap);
using SKPaint paint = new SKPaint() { FilterQuality = SKFilterQuality.High };
using SKImage image = SKImage.FromBitmap(_image);

canvas.DrawBitmap(_image, srcRect, destRect, paint);
canvas.DrawImage(image, srcRect, destRect, new SKSamplingOptions(SKCubicResampler.Mitchell));

Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SKImage.FromBitmap(_image) introduces an extra allocation/native resource for every resize-with-padding call. Since this code can run per-row in pipelines, consider using an API that draws directly from SKBitmap with SKSamplingOptions (if available in the target SkiaSharp version) to avoid creating an intermediate SKImage each time.

This issue also appears on line 393 of the same file.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In SkiaSharp 3.x, SKCanvas.DrawBitmap doesn't have an overload that accepts SKSamplingOptions — only DrawImage does. So SKImage.FromBitmap is required to use high-quality resampling. The old code's SKPaint.FilterQuality property is obsolete/removed in 3.x.

@stephentoub
Copy link
Member

@copilot address the feedback as is necessary / valuable

auto-merge was automatically disabled February 23, 2026 03:21

Head branch was pushed to by a user without write access

Copy link
Contributor Author

Copilot AI commented Feb 23, 2026

@copilot address the feedback as is necessary / valuable

Addressed in 00d95ab:

  • Fixed the inaccurate csproj comment about SkiaSharp native dependencies
  • Added IntPtr.Zero / ByteCount validation in Pixels getter

The SKImage.FromBitmap suggestion isn't actionable — in SkiaSharp 3.x, DrawBitmap doesn't support SKSamplingOptions, so DrawImage (which requires the intermediate SKImage) is the only path for high-quality resampling.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • dnceng.pkgs.visualstudio.com
    • Triggering command: /home/REDACTED/work/machinelearning/machinelearning/.dotnet/dotnet dotnet build src/Microsoft.ML.ImageAnalytics/Microsoft.ML.ImageAnalytics.csproj --no-restore (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Update to latest version of SkiaSharp

2 participants