Thursday 28 April 2016

Auto Image rotation functionality using ColdFusion.

Generally we use our mobile phones to take picture and then send it to computer for various uses. We can take a picture from mobile with any angle we want then the phone has the ability to preview the image with proper orientation. Now the problem is when we have taken a picture with up side down and send the same picture to computer, it will preview the images with upside down as the system doesn't change the orientation automatically. Now the real issue is, we have couple of images and we want to create a profile picture for each users by manipulating the same images that we have. We can't use a up side down image as a profile picture. In order to resolve this issue we have the mechanism in ColdFusion to read the image and we can find if the image is proper oriented or not.

Let's take a look to the below code:

Set an image path to a varibale.

<cfset VARIABLES.imageName = "IMG_111.JPG">

Read the image property.
   
<cfset VARIABLES.theImage = ImageRead(VARIABLES.imageName)>
Then get the orientation of that image.
<cfset VARIABLES.orientation  = ImageGetEXIFTag(VARIABLES.theImage, 'orientation')>

Use ImageGetEXIFMetadata and then check if the structKeyExists.

<cfif (NOT isNull(orientation))>   
    <!---Find the rotation degree from below string if needed--->
    <cfset VAR hasRotate = findNoCase('rotate',orientation)>       
    <cfif hasRotate>       
        <!---strip out all text in the orientation value to get the degree of orientation--->
        <cfset rotateValue =reReplace(orientation,'[^0-9]','','all')>       
        <!---Rotate and write the image if needed for the particular image if needed.--->
        <cfimage   
            action = "rotate"
            angle = "#rotateValue#"
            source = "#
VARIABLES.imgPath#"  
            destination = "#
VARIABLES.imgPath#"
            isBase64= "no"
            name = "cfimage"
            overwrite = "yes">   
    </cfif>
</cfif>  
 

Now the above snippet will query for the given image, check if the orientation is right or not, if not, then it will proper oriented.
Now try to show the same image on the UI and you can find the proper oriented image.

We can also get below information form an image by reading the EXIF data of an image:

- The date/time the pic was shoot
- Image height
- Image weight
- ISO speed rating
- Make and model of the camera
- X resolution
- Y resolution
- GPS Latitude
- GPS Latitude Ref
- GPS Longitude
- GPS Longitude Ref etc.

 

Tuesday 19 April 2016

Ingetration of Facebook and Google in ColdFusion

If we are working with some sign in functionality, we can use log in using Facebook or Google. We can get all the required info like user name, email address, phone number, address, date of birth, gender etc with out entering manually in the sign in form and it will just auto populate all the above info on the sign in form. Only we need to fetch the data from FB/Google server.

Let's start with the Facebook integration.

We have to include all the API files first.

 <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
   <script src=" //ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
 

<!-- facebook button -->
        <div style="margin:5px 0;"><a  onclick="_login();" id="fbBtn" style="padding:20px;"> Log In Using Facebook</a></div>
       
        <!-- google button -->
        <div style="margin:5px 0;"><a  id="authorize-button" onclick="handleClientLoad();" >Log In Using Google</a></div>

 
Facebook java script Code starts here.

<script type="text/javascript">
    var flag = 0;       
    $("#fbBtn").click(function(){
        flag = 1;
    });   
  // Load the SDK asynchronously
  (function(thisdocument, scriptelement, id) {
    var js, fjs = thisdocument.getElementsByTagName(scriptelement)[0];
    if (thisdocument.getElementById(id)) return;
   
    js = thisdocument.createElement(scriptelement); js.id = id;
    js.src = "//connect.facebook.net/en_US/sdk.js"; //you can use
    fjs.parentNode.insertBefore(js, fjs);
  }(document, 'script', 'facebook-jssdk'));
   
  window.fbAsyncInit = function() {
  FB.init({
    appId      : '*****07300******', //Change this APP ID to yours
    cookie     : true,  // enable cookies to allow the server to access
                        // the session
    xfbml      : true,  // parse social plugins on this page
    version    : 'v2.1' // use version 2.1
  });

  // These three cases are handled in the callback function.
  FB.getLoginStatus(function(response) {
 // $("#fbBtn").trigger("click");
    statusChangeCallback(response);
  });

  };
   
  // This is called with the results from from FB.getLoginStatus().
  function statusChangeCallback(response) {
     
    if (response.status === 'connected') {
       
      // Logged into your app and Facebook.
      _i();
    } else if (response.status === 'not_authorized') {
       
      // The person is logged into Facebook, but not your app.
      document.getElementById('status').innerHTML = 'Please log ' +
        'into this app.';
    }
  } 
 
  function _login() {
    FB.login(function(response) {
       // handle the response
       if(response.status==='connected') {
        _i();
       }
     }, {scope: 'public_profile,email'});
 }

 function _i(){
     FB.api('/me', function(response) {
         //console.log(response);           
    });
 }

</script>

Google java script code starts here.

<script type="text/javascript">
var flag=0;
$("#authorize-button").click(function(){
    flag=1;
});
var clientId = '**4876******.apps.googleusercontent.com'; // Change the Client ID to yours.
// To use in your own application, replace this API key with your own.

var apiKey = 'AI**************1L1****************F-g';

// To enter one or more authentication scopes, refer to the documentation for the API.

var scopes = 'https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email';

// Use a button to handle authentication the first time.

function handleClientLoad() {
    gapi.client.setApiKey(apiKey);
    window.setTimeout(checkAuth,1);
}

function checkAuth() {
    gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: true}, handleAuthResult);
}

function handleAuthResult(authResult) {
    var authorizeButton = document.getElementById('authorize-button');
    if (authResult && !authResult.error) {
        //authorizeButton.style.visibility = 'hidden';
        makeApiCall();
    } else {
        //authorizeButton.style.visibility = '';
        authorizeButton.onclick = handleAuthClick;
        }
    }
   
function handleAuthClick(event) {
    gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: false}, handleAuthResult);
    return false;
}

// Load the API and make an API call.  Display the results on the screen.

function makeApiCall() {
    gapi.client.load('plus', 'v1', function() {
        var request = gapi.client.plus.people.get({
        'userId': 'me'
        });
   
        var request = gapi.client.plus.people.get( {'userId' : 'me'} );
        request.execute( function(profile) {
            var email = profile['emails'].filter(function(v) {
                return v.type === 'account'; // Filter out the primary email
            })[0].value;
            var fName = profile.displayName;
        });

        request.execute(function(resp) {
            //console.log(resp);         
        });
    });
}
</script>

<script src="https://apis.google.com/js/client.js"></script>


 

Thursday 14 April 2016

Converting videos to different format/resolution and creating thumbnails using FFMPEG in ColdFusion

If we are going to create a video player application in ColdFusion, then we have to work on different aspects of the video files to upload,play and store in server.

We have different formatted video files that we can upload to our application to play, but we have to make a default format file for all so that the video player will play that particular file easily.
So, the first process would be, we have to convert all uploaded files to a .mp4 file for example. If the user uploads an .AVI file or .DAT file, then we have to convert that file to .mp4 file for better
resolution and better picture quality.

So for converting a video file to .mp4 file we can use FFMPEG plug in. Below code we can use to do that.

<cfset argString = '/c #ARGUMENTS.serverPath#\manage\ffmpeg.exe -i "#fsVideoFile#" -ar 22050 "#ARGUMENTS.serverDirPath#\#dltSpaceServerFileName#.mp4" 2>&1'>

<cfexecute name="#ARGUMENTS.name#"
    arguments="#ARGUMENTS.argument#"
    timeout="3000"
    variable="jsonInfo"
    errorVariable="errorOut"
/>

ARGUMENTS.serverPath = The path wehere you store the ffmpeg.exe file(You can download this file form FFMPEG site).
fsVideoFile = The original file uploaded by the user.
ARGUMENTS.serverDirPath = The path where you can store the new converted video file.
dltSpaceServerFileName = The new video file name.


By using the above code you can convert the video files to .mp4. You can actually convert to any of the video format by changing the .ext to the new video file name.

If it necessary, then we can also get the length of the video file using the same API. For that, we can use below code.

<cfexecute name="#ARGUMENTS.serverPath#\manage\ffprobe.exe"
    arguments="#fsVideoFile# -v quiet -print_format json -show_format -show_streams"
    timeout="3000"
    variable="jsonInfo"
    errorVariable="errorOut"
/>

This above code is responsible for getting the length or duration of the video file. We can also get the resolution of that particular video file.
We would need the resolution of the video file to know whether it is a high resolution file or not. High resolution files need more internet speed to play. We can play the video by
depending upon our internet speed. If the internet is fast then we can play the high resolution or hd video files, if not the the medium or low resolution file would be played.

We can also create different resolution files by using this API. If the user upload a high resolution video file then, we can convert it to two different resolution files.


<cfexecute name="#ARGUMENTS.serverPath#\manage\ffmpeg.exe#"
    arguments="/c #ARGUMENTS.serverPath#\manage\ffmpeg.exe -i "#fsVideoFile#" -s 800x600 -ar 22050 "#fsVideoFileLarge#" 2>&1"
    timeout="3000"
    variable="jsonInfo"
    errorVariable="errorOut"
/>


<cfexecute name="#ARGUMENTS.serverPath#\manage\ffmpeg.exe#"
    arguments="/c #ARGUMENTS.serverPath#\manage\ffmpeg.exe -i "#fsVideoFile#" -s 480x320 -ar 22050 "#fsVideoFileLarge#" 2>&1"
    timeout="3000"
    variable="jsonInfo"
    errorVariable="errorOut"
/>


Here we are creating two different resolutions files with a resolution of 800x600 and 480x320. We can dynamically switch to the different resolution files depending upon the bandwidth.

There is also a mechanism we can extract the images from the video to show as a thumbnail.

<cfexecute name="#ARGUMENTS.serverPath#\manage\ffmpeg.exe#"
    arguments="-itsoffset -4  -i #fsVideoFile# -vcodec mjpeg -vframes 1 -an -f rawvideo -s 500x300 #ARGUMENTS.serverDirPath#\images\posters\poster_#dltSpaceServerFileName#.png"
    timeout="3000"
    variable="jsonInfo"
    errorVariable="errorOut"
/>