Saturday, June 16, 2012

Text To Speech in JSP page (or HTML pages)

In this post we will show how to add text to speech support to your web pages , simplified steps will be followed for that.

We will use eSpeak which is open source project:


1) Create Java Web Application : (or HTML page)
2) Create folder JS and place the following files:
- speakWorker.js
- speakGenerator.js
- speakClient.js

3) Edit speakClient.js and change the 3rd line in the file to point to your JS folder :

speakWorker = new Worker('js/speakWorker.js');

4) Create JSP pages (or HTML page) :

a) Add the following JS imports in the header:
 <script src="js/speakGenerator.js"></script>
  <script src="js/speakClient.js"></script>

b) Add this function in the header as well:
    function textToSpeech(text){
       // you can change any of these voice characteristics
        speak(text, { amplitude: 100, wordgap: 1, pitch: 50, speed: 175 });

c) Add this div to your page body :
  <div id="audio"></div>

5) In your page use the function we have just created like this:
I have added small icon beside each filed to text to speech its content in human friendly way : Name is ..., City is ...., Country is ......

Name : <input type="text" name="name" id="name" size=50 value="Osama Oransa"><img src="images/tts.png" onclick="textToSpeech('Name is '+document.forms[0].name.value); return false" style="cursor:pointer;vertical-align: middle">

The nice thing in this open source project that it support a lot of languages and different voice with ability to tune each voice using many features and if you didn't find your language you can generate the speech generator for it.

Saturday, June 2, 2012

Accessing WebCam within JSP

I keep getting questions about how we can use web camera inside jsp files , in this post i will show you how to use the web cam from within jsp file.

We will use jQuery wrapper of flash plugin for that..
My reference in that is
There is a guide you can follow instead of my post:
Here is the simplified steps:
1.Create resources folder with the following content from the mentioned web site:
either : jscam.swf or jscam_canvas_only.swf

2.Create JSP file and put the following code:
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<title>Test Web Cam</title>
<style type="text/css">
#webcam, #canvas {
    width: 320px;
    border:20px solid #333;
    -webkit-border-radius: 20px;
    -moz-border-radius: 20px;
    border-radius: 20px;

#webcam {

#webcam > span {
    bottom: -16px;

#canvas {    border:20px solid #ccc;
</style><script type="text/javascript" src="resources/jquery-1.js"></script>
<script type="text/javascript" src="resources/jquery.js"></script>
<p id="status" style="height:22px; color:#c00;font-weight:bold;"></p>
<div id="webcam">
    <span>Your WebCam should be here!</span>

<p style="width:360px;text-align:center; ">
    <a href="javascript:webcam.capture(3);changeFilter();void(0);">Take a picture after 3 seconds</a> |
    <a href="javascript:webcam.capture();changeFilter();void(0);">Take a picture instantly</a></p>

<script type="text/javascript">
var pos = 0;
var ctx = null;
var cam = null;
var image = null;

var filter_on = false;
var filter_id = 0;

$(function() {

        var pos = 0, ctx = null, saveCB, image = [];
        var canvas = document.createElement("canvas");
        canvas.setAttribute('width', 320);
        canvas.setAttribute('height', 240); 
        if (canvas.toDataURL) {
                ctx = canvas.getContext("2d");             
                image = ctx.getImageData(0, 0, 320, 240);
                saveCB = function(data) {                       
                        var col = data.split(";");
                        var img = image;
                        for(var i = 0; i < 320; i++) {
                                var tmp = parseInt(col[i]);
                      [pos + 0] = (tmp >> 16) & 0xff;
                      [pos + 1] = (tmp >> 8) & 0xff;
                      [pos + 2] = tmp & 0xff;
                      [pos + 3] = 0xff;
                                pos+= 4;
                        if (pos >= 4 * 320 * 240) {
                                ctx.putImageData(img, 0, 0);
                                $.post("/TestWebCam/UploadServlet", {type: "data", image: canvas.toDataURL("image/png")});
                                pos = 0;
        } else {
                saveCB = function(data) {
                        pos+= 4 * 320;                       
                        if (pos >= 4 * 320 * 240) {
                                $.post("/TestWebCam/UploadServlet", {type: "pixel", image: image.join('|')});
                                pos = 0;
                width: 320,
                height: 240,
                mode: "callback",
                swffile: "resources/jscam_canvas_only.swf",
                onSave: saveCB,
                onCapture: function () {
                debug: function (type, string) {
                        console.log(type + ": " + string);


3.Create a Servlet named: UploadServlet with the following code:
package osa.ora;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

 * UploadServlet
 * Author Osama Oransa
public class UploadServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {

    private static final long serialVersionUID = 529869125345702992L;
    public UploadServlet() {

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String type = request.getParameter("type");
        String image = request.getParameter("image");
        System.out.println("SAVING>>>>>>>>>>>>>>>>>>>>Type=" + type);
        System.out.println("SAVING>>>>>>>>>>>>>>>>>>>>data=" + image);
        if (type != null) {

        String byteStr = image.split(",")[1];
        byte[] bytes = Base64.decode(byteStr);
//Now you have the image bytes ready to save in File/DB/....etc..

//Or use the pixel data for old browser and convert the pixel comma separated values into int[] then call methods similar to the following one:

public static Image getImageFromArray(int[] pixels, int width, int height) {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
WritableRaster raster = (WritableRaster) image.getData();
return image;
This will show you the encoded png data can decode it or keep it encoded , save it to DB ...etc...
If you are doing a video chat application you need to capture the images in periodic manner and upload it , you may include the source & destination ids to distribute the chat images correctly..

This code only works with integrated camera in the laptop not with USB external camera.

These are simplified steps so you can copy and paste and let it work easily.
But in case you need more details , you may refer to the original URL for more clarification on how to control it more..

Another alternative is to use the following project: