Home > Blockchain >  Ajax XMLhttprequest Post to PHP script and Rotate Image
Ajax XMLhttprequest Post to PHP script and Rotate Image

Time:11-09

I know where I have big problems but I can't seem to solve them. I am trying to rotate an image using PHP via Ajax. I just wand to rotate the image 90 degrees with each button press. Can someone please help. I know I am telling my PHP script to retrieve the $_POST['image'] variable but I'm not sending one which is why I am getting php errors. I know the php script works. I don't know if I can use the xhttp.open("GET") or not in my script either. I know there are other problems with my html and reloading the image in the tag, too. Any help greatly appreciated.

Here is my JS:

<script>

function rotateImage(){
var xhttp = new XMLHttpRequest();   
xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        document.getElementById("rotate").innerHTML =   this.responseText;
   }
};

xhttp.open("POST", "rotate.php", true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
xhttp.send("<?php echo $fileName; ?>");
}
</script>

Here is my PHP:

<?php 
    
    $image = $_POST['image'];
    $degree = 90;
    $source = imagecreatefromjpeg($image);
    // Rotate
    $rotate = imagerotate($source, $degree, 0);
    $image = imagejpeg($rotate, realpath($image), 100);
    //echo $image;
    imagedestroy($source);
    imagedestroy($rotate);

?>

And my HTML:

<div class="row justify-content-center mb-3">
    <div class="col-lg col-auto">
    <?php list($width, $height) = getimagesize($fileName); ?>     
        <div class="mb-1" id="rotate"><img class="rounded img-fluid" src="<?php echo $fileName; ?>" alt="Your Profile Photo" width="<?php echo $width; ?>" height="<?php echo $height; ?>" /></div>
        <div class="text-center"><button onClick="rotateImage()" class="btn btn-outline-primary btn-sm"><i class="fas fa-sync-alt"></i> Rotate</button></div>
  </div>

CodePudding user response:

in the question it is unknown where and how the initially declared $filename is derived or what the particular folder structure / server configuration is so the following perhaps need tweaks to suit your environment as my test site uses aliased folders outwith the site root... Anyway - the sending of a filename/filepath to PHP using Ajax( or the Fetch api as here ) is easy enough. The PHP script does what it is supposed to except that it does not return a value but the trick to forcing the browser to "reload" the image when the ajax request finishes is to append a cache busting timestamp.

Reputedly the cache:'reload' property that can be set on a Fetch request will ensure the image is not cached but I found this had no effect in this situation.

<?php
    if( $_SERVER['REQUEST_METHOD']=='POST' && isset( 
        $_POST['filename'],
        $_POST['path'],
        $_POST['dir']
    )){
        ####################
        # emulate rotate.php
        ####################
        ob_clean();
        
        $image = sprintf('%s/%s', $_POST['path'], basename( $_POST['filename'] ) );
        $angle = $_POST['dir']=='clockwise' ? -90 : 90;
        
        $source = imagecreatefromjpeg( $image );
        imagesetinterpolation( $source, IMG_MITCHELL );
        
        $rotate = imagerotate( $source, $angle, 0 );
        imagejpeg( $rotate, realpath( $image ), 100 );

        imagedestroy( $source );
        imagedestroy( $rotate );
        
        list( $width, $height, $type, $attr ) = getimagesize( $image );
        
        $args=array(
            'filename'  =>  $_POST['filename'],
            'width'     =>  $width,
            'height'    =>  $height
        );
        
        
        header('Content-Type: application/json');
        exit( json_encode( $args ) );
    }
?>
<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset='utf-8' />
        <title></title>
    </head>
    <body>
    
        <div class='row justify-content-center mb-3'>
            <div class='col-lg col-auto'>
                <?php
                
                    /*
                        $path here will be the full path and $filename
                        contains the web accessible path. As mentioned
                        my setup is complicated and relies upon aliased
                        folders outside site root.
                    */
                    $path=realpath( sprintf('%s/images/uploads', getcwd() ) );
                    $filename='images/uploads/abronsius.jpg';
                ?>     
                <div class='mb-1' id='rotate'>
                    <img class='rounded img-fluid' data-path='<?php echo $path;?>' src='<?php echo $filename; ?>' alt='Your Profile Photo' />
                </div>
                
                <div class='text-center'>
                    <button class='btn btn-outline-primary btn-sm' data-dir='clockwise'>
                        <i class='fas fa-sync-alt'></i>Rotate Clockwise
                    </button>
                    
                    <button class='btn btn-outline-primary btn-sm' data-dir='anticlockwise'>
                        <i class='fas fa-sync-alt'></i>Rotate Anti-Clockwise
                    </button>
                </div>
            </div>
        </div>
        
        
        
        <script>
            (function(){
                
                const d=document;
                const q=(e,n=d)=>n.querySelector(e);
                const qa=(e,n=d)=>n.querySelectorAll(e);
                
                qa('button.btn').forEach( bttn=>bttn.addEventListener('click',e=>{
                    let img=q('img.img-fluid');
                    
                    /* set the payload to send in the request */
                    let fd=new FormData();
                        fd.set('filename', img.src.split('?')[0] );
                        fd.set('path', img.dataset.path );
                        fd.set('dir', e.target.dataset.dir );
                    
                    let url=location.href;  //rotate.php
                    
                    /* set the request parameters */
                    let args={
                        body:fd,
                        mode:'same-origin',
                        method:'post',
                        cache:'reload', //no discernible effect
                        credentials:'same-origin'
                    };
                    /* create the request */
                    let oReq=new Request( url, args );
                    
                    /* send the request and process the response by reloading the image */
                    fetch( oReq )
                        .then( r=>r.json() )
                        .then( json=>{
                            img.src=json.filename  '?t=' ( new Date() ).getTime();
                            img.width=json.width;
                            img.height=json.height;
                        })
                        .catch( err=>console.log(err) );
                }));
            })();
        </script>
    </body>
</html>

Before After-no hard-reload required

  • Related