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
-
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