ProjectiveTransformBuilder from CSS Matrix3d transform #1744
Unanswered
NiftyImages
asked this question in
Q&A
Replies: 2 comments 2 replies
-
Hi @NiftyImages I'm going to have to do some experimentation to figure out the issue here. Our matrix transforms are normally sound. ImageSharp var matrix = new Matrix4x4(
0.578352F, -0.00235739F, 0, -1.25508e-05F,
0.0626585F, 1.00757F, 0, -0.00224878F,
0, 0, 1, 0,
-12.8798F, -80.4789F, 0, 0.999998F);
using var image = new Image<Rgba32>(200, 200, Color.Black);
image.Mutate(t =>
{
ProjectiveTransformBuilder builder = new ProjectiveTransformBuilder();
builder.AppendMatrix(matrix);
t.Transform(builder);
});
image.Save(Path.Combine(outPath, "1744.png")); I experimented with Skia also and it also does not appear render that matrix as expected. What is the size of the input shape? using (var bitmap = new SKBitmap(200, 200))
{
// How do you fill a skia image?
for (int y = 0; y < bitmap.Height; y++)
{
for (int x = 0; x < bitmap.Width; x++)
{
bitmap.SetPixel(x, y, new SKColor(0, 0, 0, 255));
}
}
SKMatrix44 matrix44 = SKMatrix44.FromColumnMajor(new[]
{
0.578352F, -0.00235739F, 0, -1.25508e-05F,
0.0626585F, 1.00757F, 0, -0.00224878F,
0, 0, 1, 0,
-12.8798F, -80.4789F, 0, 0.999998F
});
using var surface = SKSurface.Create(new SKImageInfo(200, 200, bitmap.ColorType, bitmap.AlphaType));
using var paint = new SKPaint() { FilterQuality = SKFilterQuality.High };
var canvas = surface.Canvas;
canvas.SetMatrix(matrix44.Matrix);
canvas.Clear();
canvas.DrawBitmap(bitmap, 0, 0, paint);
canvas.Flush();
using var output = File.OpenWrite(Path.Combine(outPath, "1744-skia.png"));
surface.Snapshot()
.Encode(SKEncodedImageFormat.Png, 75)
.SaveTo(output);
} |
Beta Was this translation helpful? Give feedback.
1 reply
-
I can explain why the output is cut off at least. It contains a translation component at M41, M42 which shifts the entire object up and left. Without that component you end up with the following. Normally for transforms like what you are after I would recommend using tapering. using var board = Image.Load<Rgba32>(Path.Combine(inPath, "1744-fg.png"));
using var grid = Image.Load<Rgba32>(Path.Combine(inPath, "1744-bg.jpg"));
board.Mutate(t =>
{
ProjectiveTransformBuilder builder = new ProjectiveTransformBuilder();
builder.AppendTaper(Taperside.Top, Tapercorner.Both, .4F);
t.Transform(builder);
});
int left = (grid.Width - board.Width) / 2;
grid.Mutate(x => x.DrawImage(board, new Point(left, 82), 1));
grid.Save(Path.Combine(outPath, "1744.png")); |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I am attempting to reproduce the matrix3d CSS transform in ImageSharp. I have to admit that I am out of my element here, but I was hoping that someone could point me in the right direction.
I am using MovableJS to do the warping on the web interface, and it results in a CSS Transform that looks like this:
Here is a screenshot of the interface for perspective (pun intended):

I get the values from matrix3d property and try to use a ProjectiveTransformBuilder as follows:
The result looks like this:

The matrix3d css transform is a 4x4 homogeneous matrix (documentation). I've been able to AffineTransformBuilder translations and rotation, but this is really throwing me for a loop.
Am I thinking about this correctly, is it not as simple as applying the same matrix to the image before drawing on the background?
I've been at this for a couple days now, any help would be greatly appreciated.
Beta Was this translation helpful? Give feedback.
All reactions