Image transformation

Hello,

Im looking for a solution to transform an image by coordinates like this picture below. It should be done in the app (online services like cloudinary is not an option, as it must work fast in offline mode as well).

kép

Is there any method or extension available for this transformation, im willing to pay for that as well.

Thank you very much in advance!
Din

Hello Din

There are a large number of image extensions, but none of them perform transforms as you require, though some do have basic image manipulation. I suggest you contact the developers of those extensions.
https://puravidaapps.com/extensions.php

Hello ChrisWard,

Thank you very much for your prompt information! :slight_smile:

I'l do that.

As an alternative option i'm just wondering is it possible to cope together a web viewer with a java script which does some similar transformation:

https://www.w3schools.com/cssref/tryit.asp?filename=trycss3_perspective1

I don't have java experience at all.., and the solution must be run smooth without any bug, but im just wondering if it may works for someone who has experience.

Javascript is very different from Java and w3schools is a good introduction. I think you could do it in a Web View component - in fact, there is an advanced component extension that makes it much easier to use:


This extension is compatible with App Inventor.

This is an online solution using imagemagick

$command would look something like:

convert mouse1.png -matte -virtual-pixel transparent -interpolate Spline -distort BilinearForward '0,0 0,0   0,130 40,130   100,0 100,0   100,130 70,130' png:-

mouse1 mouse1_blin

This could be possible on the device if imagemagick is installed on the device:

(but this is unlikely....)

I found a function for html canvas to make a trapezoid the other way up, with a bit of a workaround....

This should work in the webviewer, you can capture the image to get back into the app using the window.AppInventor.setWebViewString (rdataUrl) - needs converting back from base64.

image

<!DOCTYPE html>
<html>
<meta name=“viewport” content=“width=device-width, initial-scale=1.0”>

<head>
	<title>Transform</title>
	
</head>

<body>
	
	<img id="mouse" src="mouse1.png"/>
	<canvas id = "myCanvas" width="100" height="130"></canvas>
	
	<img id ="squished"/>
	<canvas id = "ymCanvas" width="100" height="130"></canvas>
	<img id ="done"/>
	
	<script>
	
	var c=document.getElementById('myCanvas');
	var ctx=c.getContext('2d');
		
	var myimg = document.getElementById('mouse');
	    
    rotateImage(ctx, myimg, 0, 0, 100, 130, 180);
    
    var rcanvas = document.getElementById('myCanvas');
    var rdataUrl = rcanvas.toDataURL();
    document.getElementById('squished').src = rdataUrl;
    
    
    
    var cd=document.getElementById('ymCanvas');
	var ctxd=cd.getContext('2d');
    
    mynewimg = document.getElementById('squished');
    
    drawTrapezoidDn(ctxd,mynewimg,0,0,100,130,70);
       
    var icanvas = document.getElementById('ymCanvas');
    var dataUrl = icanvas.toDataURL();
    document.getElementById('done').src = dataUrl;
    document.getElementById('done').style.transform = 'rotate(180deg)';
    
    
    document.getElementById('myCanvas').style.display = "none";
    document.getElementById('ymCanvas').style.display = "none";
    document.getElementById('squished').style.display = "none";

    
    function rotateImage(ctx, image, x, y, w, h, degrees){
      ctx.save();
      ctx.translate(x+w/2, y+h/2);
      ctx.rotate(degrees*Math.PI/180.0);
      ctx.translate(-x-w/2, -y-h/2);
      ctx.drawImage(image, x, y, w, h);
      ctx.restore();
    }

    function drawTrapezoidDn(ctx, img, x, y, w, h, factor) {

    var startPoint = x + w * 0.5 * (factor*0.01), // calculate top x
        xi, yi, scale = img.height / h,           // used for interpolation/scale
        startLine = y,                            // used for interpolation
        endLine = y + h;                          // abs. end line (y)

    for(; y < endLine; y++) {

        // get x position based on line (y)
        xi = interpolate(startPoint, y, x, endLine, (y - startLine) / h);

        // get scaled y position for source image
        yi = (y * scale + 0.5)|0;

        // draw the slice
        ctx.drawImage(img, 0, yi, img.width, 1,       // source line
                           xi.x, y, w - xi.x * 2, 1); // output line
    }

    // sub-function doing the interpolation        
    function interpolate(x1, y1, x2, y2, t) {
        return {
            x: x1 + (x2 - x1) * t,
            y: y1 + (y2 - y1) * t
        };
    }
}


	
	function drawTrapezoid(ctx, img, x, y, w, h, factor) {

    var startPoint = x + w * 0.5 * (factor*0.01), // calculate top x
        xi, yi, scale = img.height / h,           // used for interpolation/scale
        startLine = y,                            // used for interpolation
        endLine = y + h;                          // abs. end line (y)

    for(; y < endLine; y++) {

        // get x position based on line (y)
        xi = interpolate(startPoint, y, x, endLine, (y - startLine) / h);

        // get scaled y position for source image
        yi = (y * scale + 0.5)|0;

        // draw the slice
        ctx.drawImage(img, 0, yi, img.width, 1,       // source line
                           xi.x, y, w - xi.x * 2, 1); // output line
    }

    // sub-function doing the interpolation        
    function interpolate(x1, y1, x2, y2, t) {
        return {
            x: x1 + (x2 - x1) * t,
            y: y1 + (y2 - y1) * t
        };
    }
}
	
	
	</script>
</body>

</html>

Hello TIMAI2,

You have just made my day!!! Thanks a lot!!! Llight at the end of the tunnel.

It looks really great, but to be honest i've got lost how to implement the photo and join together.
I have created a html file and inserted your provided code and uploaded as an asset. When html viewer opens it, it displays a missing picture. image
I gues the image should be implemented in the code, but im not so familiar with html coding.

Can you please so kind and send me an aia which takes a photo or use a photo and fit it into a 4 points bounded area on the canvas.

If it works, then i can t wait to send my compensatin to you:-)

Thank you so much in adance!!!

Spent a bit of time on this, but it doesn't look like it is possible to do this "locally" - i.e. with a local html file and a local image. The reason being is that the canvas element in html5 has additional security features built in, that will not allow the export of what is on the canvas using .toDataUrl. We probably can do the transformation but will not be able to return the transformed image.

I worked up the solution using my local server, which is why it worked for me when I posted the solution, having not tried it on an app.