DEBUG and RELEASE modeI found DrawLines and DrawBeziers, but I don't see a simple function to draw a single pixel. I am using DrawLines from x,y -> x,y but it is really slow (plotting 120,000 points takes ~30 seconds).
using (var bm = new Image<Rgba32>(1280, 960))
{
for (var sample = 0; sample < total;sample++)
bm.Mutate(
ctx => ctx
.DrawLines(Rgba32.Red, 1, new PointF[] { new Vector2(p1.x, p1.y), new Vector2(p1.x, p1.y) })
.DrawLines(Rgba32.Green, 1, new PointF[] { new Vector2(p2.x, p2.y), new Vector2(p2.x, p2.y) })
.DrawLines(Rgba32.Blue, 1, new PointF[] { new Vector2(p3.x, p3.y), new Vector2(p3.x, p3.y) })
.DrawLines(Rgba32.Black, 1, new PointF[] { new Vector2(p4.x, p4.y), new Vector2(p4.x, p4.y) })
);
}
i7-6500, 16GB memory, Windows 10, .Net Core 2, Visual Studio 2017
Hi @mphipps1
Normally we would use our Gitter channel for questions such as this. It helps us stay on top of issues.
Setting individual pixels is performed via the indexer on Image<TPixel>
bm[x,y] = Rgba32.Red;
Hope that helps,
James
@mphipps1 a little note about manipulating individual pixels:
our image[x,y] indexer is way faster than the same feature in System.Drawing, but it's still not the most efficient way, if want to touch 120k pixels. We will provide lower level API-s for this through Memory<T> as soon as the newest version of the System.Memory module becomes official on NuGet.
Using the indexer took my code from 25 seconds to < 100ms. That's OUTSTANDING!
From an API design point of view, it's a little unusual to have Draw* commands and then use a different mechanism for points; maybe a good note for the documentation? Or maybe DrawPoint that is a wrapper around [x,y]?
Thanks!
I've wondered before whether we should create GetPixel SetPixel methods to act as syntactic sugar but I've never managed to convince myself that they're worth it. We're basically dealing with a 2D array so the indexer semantically works well.
The Draw- commands are specialist functions that require additional computation so I wouldn't classify them as the same API-wise.
Either way, we'll have API docs soon so discoverability will be much improved.
Manipulating individual pixels should be really considered as a primitive operation. Attempts to handle it as a high-level drawing operation will most likely end up introducing significant overhead in any image processing library :)
I've wondered before whether we should create GetPixel SetPixel methods
One benefit: it would help with discoverability (via intellisense); I had to google to find this issue and discover out how to get/set pixels.
In my opinion, no one should use individual pixel getters/setters working on (x,y) coordinate pairs. It's slow by design, because the y coordinate is unnecessarily multiplied by width on every pixel access.
Use span-based row-by-row processing instead!
That is a different issue from API discoverability, but I like the API you refer to, because I would have typed image.Pixel and found it if it was in the version I'm using (doesn't seem to be yet). I was initially looking for this kind of memory-access oriented API.
I wonder if we can improve the seo visibility of our docs?
Good point - I could have looked more into the documentation :) - I'm too lazy and use intellisense to 'learn' APIs (indexers do show up in intellisense, but not after typing a '.' obviously).
Most helpful comment
In my opinion, no one should use individual pixel getters/setters working on
(x,y)coordinate pairs. It's slow by design, because theycoordinate is unnecessarily multiplied bywidthon every pixel access.Use span-based row-by-row processing instead!