📄 cameracanvas.java
字号:
/*
* Funambol is a mobile platform developed by Funambol, Inc.
* Copyright (C) 2003 - 2007 Funambol, Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by
* the Free Software Foundation with the addition of the following permission
* added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
* WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
* WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program; if not, see http://www.gnu.org/licenses or write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA.
*
* You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
* 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License
* version 3, these Appropriate Legal Notices must retain the display of the
* "Powered by Funambol" logo. If the display of the logo is not reasonably
* feasible for technical reasons, the Appropriate Legal Notices must display
* the words "Powered by Funambol".
*
*
*/
package com.funambol.mailclient.ui.view;
import com.funambol.mailclient.loc.Localization;
import com.funambol.mailclient.loc.LocalizedMessages;
import com.funambol.mailclient.ui.controller.AppProperties;
import com.funambol.mailclient.ui.controller.Theme;
import com.funambol.mailclient.ui.controller.UIController;
import com.funambol.mailclient.ui.utils.*;
import com.funambol.util.Log;
import com.funambol.util.MailDateFormatter;
import com.funambol.util.StringUtil;
import java.util.Date;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.Item;
import javax.microedition.lcdui.StringItem;
import javax.microedition.media.Manager;
import javax.microedition.media.MediaException;
import javax.microedition.media.Player;
import javax.microedition.media.control.GUIControl;
import javax.microedition.media.control.VideoControl;
import javax.microedition.midlet.MIDlet;
/**
* a canvas that allows the user to take photos with the phone camera.
*
*
*
*/
public class CameraCanvas extends Canvas
implements CommandListener {
// commands
private Command capture;
private Command fireCommand;
// mmapi stuff
private Player player = null;
private VideoControl video = null;
// the image
private Image i;
// size of the frame surrounding the image
private int BORDER = 3;
private PhotoTaker photoTaker;
public CameraCanvas() {
//adding commands
capture = new Command(Localization.getMessages().CAPTURE_LABEL, Command.OK, 1);
addCommand(UIController.cancelCommand);
addCommand(capture);
fireCommand = capture;
setCommandListener(this);
// starting the thread that will take the photo
photoTaker = new PhotoTaker(this);
UIController.getThreadPool().startThread(photoTaker);
showCamera();
}
/**
* stop the player if needed
*/
public void stopPlayer() {
if (player != null) {
try {
player.close();
} catch (IllegalStateException ex) {
// nothing to be worried, we're already stopped
Log.info("player already closed");
}
}
}
public void commandAction(Command c, Displayable d) {
if (c == capture) {
SendPhotoScreen sfs = new SendPhotoScreen();
UIController.display.setCurrent(sfs);
photoTaker.takePhoto();
} else if (c == UIController.cancelCommand) {
//stopping player before going back
stopPlayer();
UIController.showBackScreen();
}
}
// create player object and set up the video
// you're going to get in your photo
public void showCamera() {
try {
player = Manager.createPlayer("capture://video");
player.realize();
video = (VideoControl) player.getControl(
"VideoControl");
// this tells the video that we want the image to be
// rendered on the current canvas
video.initDisplayMode(VideoControl.USE_DIRECT_VIDEO, this);
int w = video.getSourceWidth();
int h = video.getSourceHeight();
int screenw = getWidth() - 4 * BORDER;
int screenh = getHeight() - 4 * BORDER;
// we want to resize the video to see
// how the shot will look
int ratiow = 100 * screenw / w;
int ratioh = 100 * screenh / h;
// this is to find the best ratio to
// resize the image without deformations
int ratio = Math.min(ratiow, ratioh);
// computing final size of the video
int videow = w * ratio / 100;
int videoh = h * ratio / 100;
video.setDisplaySize(videow, videoh);
//leaving some space to paint the frame
video.setDisplayLocation(2 * BORDER, 2 * BORDER);
// start the player
player.start();
video.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
Log.error("showcamera exception " + e.toString());
}
}
protected void paint(Graphics graphics) {
// background
graphics.setColor(UIController.getDrawer().getGraphicalTheme().getBackgroundColor());
graphics.fillRect(0, 0, getWidth(), getHeight());
/*// image frame
graphics.setColor(UIController.getDrawer().getGraphicalTheme().getForegroundColor());
graphics.fillRect(BORDER, BORDER, video.getDisplayWidth() + 2 * BORDER, video.getDisplayHeight() + 2 * BORDER);
*/
}
private void setPhoto(ImageAttachment image) {
//#ifndef noPhoto
UIController.showSendPhotoScreen(image);
//#endif
stopPlayer();
}
protected void keyPressed(int keyCode) {
int dir = getGameAction(keyCode);
if (dir == Canvas.FIRE) {
commandAction(fireCommand, this);
}
}
/**
* an helper class that sleeps till the user request to take the photo
*
*/
private class PhotoTaker implements Runnable {
private CameraCanvas canvas;
private Object lock = new Object();
// using format string to be ifdef-ready
private String format = null;
int shformat;
private final int PHOTO_QUALITY = 90; // percentage
public PhotoTaker(CameraCanvas canvas) {
this.canvas = canvas;
String jadshformat =
UIController.appProperties.get(AppProperties.SH_FORMAT);
if ((jadshformat != null) && (!jadshformat.equals(""))) {
shformat = Integer.parseInt(jadshformat);
switch (shformat) {
case 160:
format = "encoding=png&width=160&height=120";
break;
case 320:
format = "encoding=png&width=320&height=240";
break;
case 640:
format = "encoding=jpeg&quality=" + PHOTO_QUALITY + "&width=640&height=480";
break;
case 288:
format = "encoding=jpeg&width=288&height=352";
break;
default:
format = null;
break;
}
}
}
public void takePhoto() {
// we are syncronized on the lock resource
// here we free the resource
synchronized (lock) {
lock.notify();
}
}
public void run() {
while (true) {
try {
synchronized (lock) {
// waiting for the resource
lock.wait();
byte[] data;
String[] encodings = {
format,
getSupportedEncodings(),
null
};
int i = 0;
String encoding = null;
String imageExt = "png"; // default is png
for (i = 0; i < encodings.length; i++) {
try {
encoding = encodings[i];
Log.info("Doing Snapshot with format: " + encoding);
if (encoding != null) {
int andIndex = encoding.indexOf("&");
if (andIndex != -1) {
imageExt = encoding.substring(encoding.indexOf("encoding=") + 9, andIndex);
} else {
imageExt = encoding.substring(encoding.indexOf("encoding=") + 9);
}
Log.info("Image Attachment extension: " + imageExt);
}
//frees memory before send photo
try {
System.gc();
Thread.sleep(1);
} catch (InterruptedException ex) {
// just ignore it
Log.error("interrupted exception freeing memory");
}
data = video.getSnapshot(encoding);
ImageAttachment im =
new ImageAttachment(data, getImageName(imageExt), getContentType(imageExt));
canvas.setPhoto(im);
break;
} catch (MediaException ex) {
Log.info("[getsnapshot] unsupported encoding format: " + encoding + " " + ex);
if (i == 2) {
UIController.showErrorAlert("" + ex, canvas);
lock.notify();
break;
}
continue;
} catch (SecurityException ex) {
ex.printStackTrace();
Log.error("getsnapshot: permission to take photo denied " + ex.toString());
UIController.showErrorAlert(Localization.getMessages().PERMISSION_TO_TAKE_PHOTO_DENIED, canvas);
lock.notify();
break;
}
}
}
} catch (InterruptedException ex) {
//TODO: handle
ex.printStackTrace();
Log.error("interrupted exception running camera canvas thread");
} catch (Exception e) {
Log.error("generic exception in camera canvas thread: " + e.toString());
}
}
}
/**
* return the image name based on current time. format is hhmmss.png
*/
private String getImageName(String ext) {
Date d = new Date();
String date = MailDateFormatter.dateToUTC(d);
return date + "." + getImageFileExtension(ext);
}
/**
* return the content type. now is "image/jpeg"
*/
private String getContentType(String type) {
if (type.equals("jpg")) {
return "image/jpeg";
} else {
return "image/png";
}
}
/**
* return the content type. now is "image/jpeg"
*/
private String getImageFileExtension(String ext) {
if (ext.equals("jpeg")) {
return "jpg";
} else {
return "png";
}
}
}
private String getSupportedEncodings() {
String[] encoding = StringUtil.split(System.getProperty("video.snapshot.encodings"), " ");
for (int i = 0; i < encoding.length; i++) {
if (encoding[i].indexOf("encoding") > 0) {
return encoding[i];
}
}
return null;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -