Sunday, December 26, 2010

Using Gmail to Send Emails (with attachments)



In this post we will learn how to send attachment in email like file or image also how to embed the image inside the email.

The good thing about Gmail is that we can use it to send emails as SMTP server.

Here is the needed steps:

1.Define the following attributes:

smtpServerIP = smtp.gmail.com;
smtpServerPort = 465;
smtpServerUser = Your gmail email;
smtpServerPassword = Your gmail email password;

2.The following is mail sending method:

public void sendMail(final String[] toUserEmail, final String subject, final String body,final BufferedImage myImage, final File file, final boolean isPicture) {

new Thread() {
@Override
public void run() {
try {
Properties props = new Properties();
props.put("mail.smtp.host", smtpServerIP);
props.put("mail.smtp.port", smtpServerPort);
props.put("mail.smtp.auth", "true");
//props.put("mail.debug", "false");
props.put("mail.smtp.socketFactory.port", smtpServerPort);
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");
Authenticator auth = new SMTPAuthenticator();
Session session = Session.getInstance(props, auth);
//session.setDebug(false);
// create a message
Message msg = new MimeMessage(session);
msg.setHeader("HomeMonitor", "By Osama Oransa");
// set the from and to address
InternetAddress addressFrom = new InternetAddress(smtpServerUser);
msg.setFrom(addressFrom);
InternetAddress[] addressTo = new InternetAddress[toUserEmail.length];
for (int i = 0; i < toUserEmail.length; i++) {
addressTo[i] = new InternetAddress(toUserEmail[i]);
}
msg.setRecipients(Message.RecipientType.TO, addressTo);
String[] messageParts = body.split("##");
//no thing attached
if (messageParts.length == 1) {
msg.setContent(body, "text/html");
//image is attached
//body is text and image
} else if (messageParts.length == 2) {
MimeMultipart multipart = new MimeMultipart();//"related");
MimeBodyPart messageBodyPart;
// first part html text before image
messageBodyPart = new MimeBodyPart();
if (isPicture) {
messageBodyPart.setContent(messageParts[0] + "

" + messageParts[1], "text/html");
multipart.addBodyPart(messageBodyPart);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
boolean readingImageResult;
try {
readingImageResult = ImageIO.write(myImage, "jpg", byteArrayOutputStream);
System.out.println("Result of writing the image is " + readingImageResult);
} catch (IOException ex) {
ex.printStackTrace();
}
byte[] byteArray = byteArrayOutputStream.toByteArray();
MimeBodyPart messageBodyPart2 = new MimeBodyPart();
DataSource fds = new ByteArrayDataSource(byteArray, "image/jpg");
messageBodyPart2.setDataHandler(new DataHandler(fds));
messageBodyPart2.setHeader("Content-ID", "");
multipart.addBodyPart(messageBodyPart2);
msg.setContent(multipart);
} else {
//is file attached, like voice....
messageBodyPart.setContent(messageParts[0] + "
" + messageParts[1], "text/html");
multipart.addBodyPart(messageBodyPart);
// Part two is attachment
MimeBodyPart messageBodyPart2 = new MimeBodyPart();
DataSource source = new FileDataSource(file);
messageBodyPart2.setDataHandler(new DataHandler(source));
messageBodyPart2.setFileName(file.getName());
multipart.addBodyPart(messageBodyPart2);
msg.setContent(multipart);
}
}
// Setting the Subject and Content Type
msg.setSubject(subject);
Transport.send(msg);
System.out.println("Message sent to " + toUserEmail + " OK.");
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("Exception " + ex);
}
}
}.start();
}

3. Define inner class for authentication:

// Also include an inner class that is used for authentication purposes
private class SMTPAuthenticator extends javax.mail.Authenticator {
@Override
public PasswordAuthentication getPasswordAuthentication() {
System.out.println("call authentication");
String username = smtpServerUser;
String password = smtpServerPassword;
return new PasswordAuthentication(username, password);
}
}


The method send email either plain email or with attachement or with embeded picture in it.
final String[] toUserEmail, final String subject, final String body,final BufferedImage myImage, final File file, final boolean isPicture)

It takes array of emails to send to them, subject and body of the email.
Then it take optional image or file to attach (not both so you can modify the method to include this extra-requirements)

The boolean isPicture is used to deal with picture as embedded object..

In case you need to attach image or file , you need to place in the body of the email the token ## file name or image name (or title).

This is easy usage method for sending emails with attachment and in our example we used Gmail as SMTP server.

Wednesday, December 22, 2010

Java Home Monitor Application

New Open source application is released..

URL:

http://sourceforge.net/projects/home-monitor/

In summary :

This application used to monitor your home via email using your USB web camera and microphone , there is a lot of configurations to customize it upon needs. A motion detection is also supported.

Features:

* Use USB web camera and microphone
* Work while computer is locked
* Differentiate between capturing the image/audio and sending them in email as attachments
* Configurable for customization of the needs
* Motion detection to send out of configuration shots.
* Can send emails using gmail user account.
* Captured media stored in specified directory and send some according to the configurations.
* Depends on LTI-CIVIL for accessing the USB camera: http://lti-civil.org/
* You can download the library and pick the needed library for the operating system
* Run over any operating system.
* Tested well in Java 5 , still there is issue in email sending with attachment in Java 6.
* Optionally Play sound/recorded message on repeated motion detection.
* Wait for configurable time before start capturing.
* In Version 1.1 (1) a new configuration item to delete old picture if new matched it.
* (2) Also FTP Support is added.

Future Enhancements:

-Detect motion detection in voice files ..
-Send video files (combined video+audio).
-Send SMS through any free gateway.

Saturday, December 18, 2010

Capture photo / image from Web Cam / USB Camera using Java

In this post we will show how to use a USB camera to capture a picture from inside a Java application..
We will use the library LTI-CIVIL which is part of FMJ (Freedom for Media in Java)



Let's go through the needed steps:

1.Download LTI-CIVIL:

Which is a Java library for capturing images from a video source such as a USB camera. It provides a simple API and does not depend on or use JMF!
The advantage behind this library that it doesn't depend on JMF (which is almost very old now)
The project URL: http://lti-civil.org/
Download URL: http://sourceforge.net/projects/lti-civil/files/

Extract the zip/tar file and you will find 2 things we will use:
a) lti-civil-no_s_w_t.jar
b) native folder contain the native libraries according to the operating system , pick the one for the system you are using.


2.Create the Java App:

Add to the class-path of the project the jar file and the native library folder.
To Run the project as jar file , you can use the JVM parameter:

-Djava.library.path=".....\native\win32-x86" to add the library to the class path of the jar file.


3.Create a class file:

Name it like TestWebCam implements CaptureObserver

4. Define the following instance variables:

JButton start = null;
JButton shot = null;
JButton stop = null;
CaptureStream captureStream = null;
boolean takeShot=false;

5.In the constructor:

Add the following code to initialize the capturing device:

public TestWebCam() {
CaptureSystemFactory factory = DefaultCaptureSystemFactorySingleton.instance();
CaptureSystem system;
try {
system = factory.createCaptureSystem();
system.init();
List list = system.getCaptureDeviceInfoList();
int i = 0;
if (i < list.size()) {
CaptureDeviceInfo info = (CaptureDeviceInfo) list.get(i);
System.out.println((new StringBuilder()).append("Device ID ").append(i).append(": ").append(info.getDeviceID()).toString());
System.out.println((new StringBuilder()).append("Description ").append(i).append(": ").append(info.getDescription()).toString());
captureStream = system.openCaptureDeviceStream(info.getDeviceID());
captureStream.setObserver(TestWebCam.this);
}
} catch (CaptureException ex) {
ex.printStackTrace();
}
//UI work of the program
JFrame frame = new JFrame();
frame.setSize(7000, 800);
JPanel panel = new JPanel();
frame.setContentPane(panel);
frame.setVisible(true);
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
start = new JButton("Start");
stop = new JButton("Stop");
shot = new JButton("Shot");
panel.add(start);
panel.add(stop);
panel.add(shot);
panel.revalidate();
start.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
captureStream.start();
} catch (CaptureException ex) {
ex.printStackTrace();
}
}
});
stop.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
captureStream.stop();
} catch (CaptureException ex) {
ex.printStackTrace();
}
}
});
shot.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
takeShot=true;
}
});
}

6.Add the following 2 methods mandated by the implemented interface CaptureObserver:

public void onNewImage(CaptureStream stream, Image image) {
if(!takeShot) return;
takeShot=false;
System.out.println("New Image Captured");
byte bytes[] = null;
try {
if (image == null) {
bytes = null;
return;
}
try {
ByteArrayOutputStream os = new ByteArrayOutputStream();
JPEGImageEncoder jpeg = JPEGCodec.createJPEGEncoder(os);
jpeg.encode(AWTImageConverter.toBufferedImage(image));
os.close();
bytes = os.toByteArray();
} catch (IOException e) {
e.printStackTrace();
bytes = null;
} catch (Throwable t) {
t.printStackTrace();
bytes = null;
}
if (bytes == null) {
return;
}
ByteArrayInputStream is = new ByteArrayInputStream(bytes);
File file = new File("/img" + Calendar.getInstance().getTimeInMillis() + ".jpg");
FileOutputStream fos = new FileOutputStream(file);
fos.write(bytes);
fos.close();
BufferedImage myImage = ImageIO.read(file);
shot.setText("");
shot.setIcon(new ImageIcon(myImage));
shot.revalidate();
} catch (IOException ex) {
ex.printStackTrace();
}
}

public void onError(CaptureStream stream, CaptureException ce) {
System.out.println("Error!");
}

7.Optionally, to Covert image to Gray Scale:

In case you need to convert it into Gray scale (for image processing purposes you can replace the following line with this block:

Old Line:
shot.setIcon(new ImageIcon(myImage));

New Block:

//Convert myImage to gray scale
BufferedImage imageGray = new BufferedImage(myImage.getWidth(), myImage.getHeight(),
BufferedImage.TYPE_BYTE_GRAY);
Graphics g = imageGray.getGraphics();
g.drawImage(myImage, 0, 0, null);
g.dispose();
shot.setIcon(new ImageIcon(imageGray));


8.Add main method to this class to run it:

public static void main(String args[])
throws Exception {
TestWebCam test = new TestWebCam();
}

9.Connect the USB Camera and run the application...

It should show 3 buttons : Start , Stop and Shot..
Click on start , then on shot, it will get you the current web camera image, move the web camera and take another shot by click on the picture to update it.


**Possible Issues:

1.Native library is not in the classpath.
2.Wrong native library is used.
3.USB Camera is not correct connected or installed.
4.Another program is running connected to the camera resource (you may be running your program 2 times)

You can use the CaptureStream parameter as well, but i think if you need to capture a streaming web cam , it would better to use images with intervals.


*** UPDATE: based on a lot of requests asking about using it to capture videos, here is the new post discussing the topic in details:

WebCam Video Capture in Java

Hope this help more to address this issue in particular.

*** UPDATE|: based on number of requests to access the web camera from JSP file , here is a link to a post discussing the how to in details:

Accessing Webcam Within JSP


*** UPDATE: if you want sample code , please download my other open source project Interactive4J, it has example for video and images.