基于web的android图像处理示例(Win7+Apache+PHP+Matlab+Android)【转】
本文将介绍C/S模式的图像处理系统。C/S的框架已经在[1]中作了简单的介绍。[2]中介绍了如何搭建基于android和WAMP5的B/S模式的本机测试平台。本系统是在[4]中介绍的基础上开发的,有关图像显示和本地图像处理的框架可以参看[4]; @author:郑海波 zhb931706659@126.com
转载请声明:http://blog.csdn.net/nuptboyzhb/article/details/7945249
实验结果展示:(图像的DCT变换)
实验平台: 服务器:Windows 7+Apache+MySQL+PHP 客户端:Android 开发工具:Eclipse+ADT+AVD 我们先看客户端(Client)的android开发 1.图像处理框架: 本次试验的图像处理框架我们依然使用[4]的实验平台。该实验平台已经实现了图像的打开,保存,摄像,截屏,显示和简单的图像处理算法等功能。 我们本次试验,需要用到该框架的图像打开,显示,保存等基本功能。 2.客户端的核心 在客户端,C/S模式的核心就是如何将本机数据发送到服务器,并从服务器中下载处理完后的数据。由于连接服务器,发送,接收等需要较长时间,因此 我们将其过程封装到一个AsyncTask派生的类中,代码如下: [java code]
- publicclass ServerTask extends AsyncTask<String, Integer , Void>
- {
- publicbyte[] dataToServer;
- //Task state
- privatefinalint UPLOADING_PHOTO_STATE = 0;
- privatefinalint SERVER_PROC_STATE = 1;
- private ProgressDialog dialog;
- //upload photo to server
- HttpURLConnection uploadPhoto(FileInputStream fileInputStream)
- {
- //final String serverFileName = "test"+ (int) Math.round(Math.random()*1000) + ".jpg";
- final String serverFileName = "test.jpg";
- final String lineEnd = "\r\n";
- final String twoHyphens = "--";
- final String boundary = "*****";
- Log.e("msg","begin HttpURLConnection......");
- try
- {
- URL url = new URL(SERVERURL);
- // Open a HTTP connection to the URL
- final HttpURLConnection conn = (HttpURLConnection)url.openConnection();
- // Allow Inputs
- conn.setDoInput(true);
- // Allow Outputs
- conn.setDoOutput(true);
- // Don't use a cached copy.
- conn.setUseCaches(false);
- // Use a post method.
- conn.setRequestMethod("POST");
- conn.setRequestProperty("Connection", "Keep-Alive");
- conn.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundary);
- DataOutputStream dos = new DataOutputStream( conn.getOutputStream() );
- dos.writeBytes(twoHyphens + boundary + lineEnd);
- dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" + serverFileName +"\"" + lineEnd);
- dos.writeBytes(lineEnd);
- // create a buffer of maximum size
- int bytesAvailable = fileInputStream.available();
- int maxBufferSize = 1024;
- int bufferSize = Math.min(bytesAvailable, maxBufferSize);
- byte[] buffer = newbyte[bufferSize];
- // read file and write it into form...
- int bytesRead = fileInputStream.read(buffer, 0, bufferSize);
- while (bytesRead > 0)
- {
- dos.write(buffer, 0, bufferSize);
- bytesAvailable = fileInputStream.available();
- bufferSize = Math.min(bytesAvailable, maxBufferSize);
- bytesRead = fileInputStream.read(buffer, 0, bufferSize);
- }
- // send multipart form data after file data...
- dos.writeBytes(lineEnd);
- dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
- publishProgress(SERVER_PROC_STATE);
- // close streams
- fileInputStream.close();
- dos.flush();
- Log.e("msg","upload finished!");
- return conn;
- }
- catch (MalformedURLException ex){
- Log.e(TAG, "error: " + ex.getMessage(), ex);
- returnnull;
- }
- catch (IOException ioe){
- Log.e(TAG, "error: " + ioe.getMessage(), ioe);
- returnnull;
- }
- }
- //get image result from server and display it in result view
- void getResultImage(HttpURLConnection conn){
- // retrieve the response from server
- InputStream is;
- try {
- is = conn.getInputStream();
- //get result image from server
- resultForWebImage = BitmapFactory.decodeStream(is);
- is.close();
- IsShowingResult = true;
- Log.d("msg","download finished!");
- } catch (IOException e) {
- Log.e(TAG,"getResultImage:"+e.toString());
- e.printStackTrace();
- }
- }
- //Main code for processing image algorithm on the server
- void processImage(String inputImageFilePath){
- publishProgress(UPLOADING_PHOTO_STATE);
- File inputFile = new File(inputImageFilePath);
- try {
- //create file stream for captured image file
- FileInputStream fileInputStream = new FileInputStream(inputFile);
- //upload photo
- final HttpURLConnection conn = uploadPhoto(fileInputStream);
- //get processed photo from server
- if (conn != null){
- getResultImage(conn);
- //String download="http://10.10.145.154/EE368_Android_Tutorial3_Server/computeSIFTOnSCIEN.php";
- }
- fileInputStream.close();
- }
- catch (FileNotFoundException ex){
- Log.e(TAG, "processImage"+ex.toString());
- }
- catch (IOException ex){
- Log.e(TAG, "processImage"+ex.toString());
- }
- }
- public ServerTask() {
- dialog = new ProgressDialog(SystemMain.this);
- }
- protectedvoid onPreExecute() {
- this.dialog.setMessage("Photo captured");
- this.dialog.show();
- }
- @Override
- protected Void doInBackground(String... params) { //background operation
- String uploadFilePath = params[0];
- processImage(uploadFilePath);
- //release camera when previous image is processed
- mCameraReadyFlag = true;
- returnnull;
- }
- //progress update, display dialogs
- @Override
- protectedvoid onProgressUpdate(Integer... progress) {
- if(progress[0] == UPLOADING_PHOTO_STATE){
- dialog.setMessage("Uploading");
- dialog.show();
- }
- elseif (progress[0] == SERVER_PROC_STATE){
- if (dialog.isShowing()) {
- dialog.dismiss();
- }
- dialog.setMessage("Processing");
- dialog.show();
- }
- }
- @Override
- protectedvoid onPostExecute(Void param) {
- if (dialog.isShowing()) {
- dialog.dismiss();
- if(IsShowingResult){
- ShowImage(resultForWebImage, 2);
- IsShowingResult=false;
- }
- }
- }
- }
public class ServerTask extends AsyncTask<String, Integer , Void> { public byte[] dataToServer; //Task state private final int UPLOADING_PHOTO_STATE = 0; private final int SERVER_PROC_STATE = 1; private ProgressDialog dialog; //upload photo to server HttpURLConnection uploadPhoto(FileInputStream fileInputStream) { //final String serverFileName = "test"+ (int) Math.round(Math.random()*1000) + ".jpg"; final String serverFileName = "test.jpg"; final String lineEnd = "\r\n"; final String twoHyphens = "--"; final String boundary = "*****"; Log.e("msg","begin HttpURLConnection......"); try { URL url = new URL(SERVERURL); // Open a HTTP connection to the URL final HttpURLConnection conn = (HttpURLConnection)url.openConnection(); // Allow Inputs conn.setDoInput(true); // Allow Outputs conn.setDoOutput(true); // Don't use a cached copy. conn.setUseCaches(false); // Use a post method. conn.setRequestMethod("POST"); conn.setRequestProperty("Connection", "Keep-Alive"); conn.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundary); DataOutputStream dos = new DataOutputStream( conn.getOutputStream() ); dos.writeBytes(twoHyphens + boundary + lineEnd); dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" + serverFileName +"\"" + lineEnd); dos.writeBytes(lineEnd); // create a buffer of maximum size int bytesAvailable = fileInputStream.available(); int maxBufferSize = 1024; int bufferSize = Math.min(bytesAvailable, maxBufferSize); byte[] buffer = new byte[bufferSize]; // read file and write it into form... int bytesRead = fileInputStream.read(buffer, 0, bufferSize); while (bytesRead > 0) { dos.write(buffer, 0, bufferSize); bytesAvailable = fileInputStream.available(); bufferSize = Math.min(bytesAvailable, maxBufferSize); bytesRead = fileInputStream.read(buffer, 0, bufferSize); } // send multipart form data after file data... dos.writeBytes(lineEnd); dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd); publishProgress(SERVER_PROC_STATE); // close streams fileInputStream.close(); dos.flush(); Log.e("msg","upload finished!"); return conn; } catch (MalformedURLException ex){ Log.e(TAG, "error: " + ex.getMessage(), ex); return null; } catch (IOException ioe){ Log.e(TAG, "error: " + ioe.getMessage(), ioe); return null; } } //get image result from server and display it in result view void getResultImage(HttpURLConnection conn){ // retrieve the response from server InputStream is; try { is = conn.getInputStream(); //get result image from server resultForWebImage = BitmapFactory.decodeStream(is); is.close(); IsShowingResult = true; Log.d("msg","download finished!"); } catch (IOException e) { Log.e(TAG,"getResultImage:"+e.toString()); e.printStackTrace(); } } //Main code for processing image algorithm on the server void processImage(String inputImageFilePath){ publishProgress(UPLOADING_PHOTO_STATE); File inputFile = new File(inputImageFilePath); try { //create file stream for captured image file FileInputStream fileInputStream = new FileInputStream(inputFile); //upload photo final HttpURLConnection conn = uploadPhoto(fileInputStream); //get processed photo from server if (conn != null){ getResultImage(conn); //String download="http://10.10.145.154/EE368_Android_Tutorial3_Server/computeSIFTOnSCIEN.php"; } fileInputStream.close(); } catch (FileNotFoundException ex){ Log.e(TAG, "processImage"+ex.toString()); } catch (IOException ex){ Log.e(TAG, "processImage"+ex.toString()); } } public ServerTask() { dialog = new ProgressDialog(SystemMain.this); } protected void onPreExecute() { this.dialog.setMessage("Photo captured"); this.dialog.show(); } @Override protected Void doInBackground(String... params) { //background operation String uploadFilePath = params[0]; processImage(uploadFilePath); //release camera when previous image is processed mCameraReadyFlag = true; return null; } //progress update, display dialogs @Override protected void onProgressUpdate(Integer... progress) { if(progress[0] == UPLOADING_PHOTO_STATE){ dialog.setMessage("Uploading"); dialog.show(); } else if (progress[0] == SERVER_PROC_STATE){ if (dialog.isShowing()) { dialog.dismiss(); } dialog.setMessage("Processing"); dialog.show(); } } @Override protected void onPostExecute(Void param) { if (dialog.isShowing()) { dialog.dismiss(); if(IsShowingResult){ ShowImage(resultForWebImage, 2); IsShowingResult=false; } } } }
此时,我们只需要在适当的时候,启动这个任务。当用户点击send按钮时,启动服务: [java code]
- sendBtnListener=new OnClickListener() {
- @Override
- publicvoid onClick(View v) {
- // TODO Auto-generated method stub
- if(myBitmap!=null){
- mClientForWeb.compressByteImage(myBitmap, 75);;
- ServerTask task = new ServerTask();
- Log.e("msg","new ServerTask finished!");
- task.execute(Environment.getExternalStorageDirectory().toString() +mClientForWeb.INPUT_IMG_FILENAME);
- }
- }
- };
sendBtnListener=new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub if(myBitmap!=null){ mClientForWeb.compressByteImage(myBitmap, 75);; ServerTask task = new ServerTask(); Log.e("msg","new ServerTask finished!"); task.execute(Environment.getExternalStorageDirectory().toString() +mClientForWeb.INPUT_IMG_FILENAME); } } };
服务器端的PHP代码和matlab代码 1.服务器端的执行流程 首先,PHP获取到客户端发送过来的数据,然后在PHP中调用matlab代码对数据进行处理。PHP将处理后的结果再发回给客户端 2.本次试验 本次试验我们将实现图像的DCT变换。也即是:对客户端发送的图像做DCT变换,然后将变换后的图像发回给客户端。 如下图: [图]
3.matlab的执行方式 我们用命令行的方式执行matlab代码,参见[3]。在PHP中,我们只需要用exec函数调用相应的指令即可。 4.PHP代码 [php code]
- <?php
- #-------------------------------------------------------------------------------
- # EE368 Digital Image Processing
- # Android Tutorial #3: Server-Client Interaction Example for Image Processing
- # Author: Derek Pang (dcypang@stanford.edu), David Chen (dmchen@stanford.edu)
- #------------------------------------------------------------------------------
- #functionfor streaming file to client
- function streamFile($location, $filename, $mimeType='application/octet-stream')
- { if(!file_exists($location))
- { header ("HTTP/1.0 404 Not Found");
- return;
- }
- $size=filesize($location);
- $time=date('r',filemtime($location));
- #html response header
- header('Content-Description: File Transfer');
- header("Content-Type: $mimeType");
- header('Cache-Control: public, must-revalidate, max-age=0');
- header('Pragma: no-cache');
- header('Accept-Ranges: bytes');
- header('Content-Length:'.($size));
- header("Content-Disposition: inline; filename=$filename");
- header("Content-Transfer-Encoding: binary\n");
- header("Last-Modified: $time");
- header('Connection: close');
- ob_clean();
- flush();
- readfile($location);
- }
- #**********************************************************
- #Main script
- #**********************************************************
- #<1>set target path for storing photo uploads on the server
- $photo_upload_path = "./upload/";
- $photo_upload_path = $photo_upload_path. basename( $_FILES['uploadedfile']['name']);
- #<2>set target path for storing result on the server
- $processed_photo_output_path = "./output/processed_";
- $processed_photo_output_path = $processed_photo_output_path. basename( $_FILES['uploadedfile']['name']);
- $downloadFileName = 'processed_' . basename( $_FILES['uploadedfile']['name']);
- #<3>modify maximum allowable file size to 10MB and timeout to 300s
- ini_set('upload_max_filesize', '10M');
- ini_set('post_max_size', '10M');
- ini_set('max_input_time', 300);
- ini_set('max_execution_time', 300);
- #<4>Get and stored uploaded photos on the server
- if(copy($_FILES['uploadedfile']['tmp_name'], $photo_upload_path)) {
- #<5> execute matlab image processing algorithm
- #example: Compute and display SIFT features using VLFeat and Matlab
- $command = "matlab -nojvm -nodesktop -nodisplay -r \"ImageDCT('$photo_upload_path','$processed_photo_output_path');exit\"";
- exec($command);
- #<6>stream processed photo to the client
- streamFile($processed_photo_output_path, $downloadFileName,"application/octet-stream");
- } else{
- echo"There was an error uploading the file to $photo_upload_path !";
- }
- ?>
<?php #------------------------------------------------------------------------------- # EE368 Digital Image Processing # Android Tutorial #3: Server-Client Interaction Example for Image Processing # Author: Derek Pang (dcypang@stanford.edu), David Chen (dmchen@stanford.edu) #------------------------------------------------------------------------------ #function for streaming file to client function streamFile($location, $filename, $mimeType='application/octet-stream') { if(!file_exists($location)) { header ("HTTP/1.0 404 Not Found"); return; } $size=filesize($location); $time=date('r',filemtime($location)); #html response header header('Content-Description: File Transfer'); header("Content-Type: $mimeType"); header('Cache-Control: public, must-revalidate, max-age=0'); header('Pragma: no-cache'); header('Accept-Ranges: bytes'); header('Content-Length:'.($size)); header("Content-Disposition: inline; filename=$filename"); header("Content-Transfer-Encoding: binary\n"); header("Last-Modified: $time"); header('Connection: close'); ob_clean(); flush(); readfile($location); } #********************************************************** #Main script #********************************************************** #<1>set target path for storing photo uploads on the server $photo_upload_path = "./upload/"; $photo_upload_path = $photo_upload_path. basename( $_FILES['uploadedfile']['name']); #<2>set target path for storing result on the server $processed_photo_output_path = "./output/processed_"; $processed_photo_output_path = $processed_photo_output_path. basename( $_FILES['uploadedfile']['name']); $downloadFileName = 'processed_' . basename( $_FILES['uploadedfile']['name']); #<3>modify maximum allowable file size to 10MB and timeout to 300s ini_set('upload_max_filesize', '10M'); ini_set('post_max_size', '10M'); ini_set('max_input_time', 300); ini_set('max_execution_time', 300); #<4>Get and stored uploaded photos on the server if(copy($_FILES['uploadedfile']['tmp_name'], $photo_upload_path)) { #<5> execute matlab image processing algorithm #example: Compute and display SIFT features using VLFeat and Matlab $command = "matlab -nojvm -nodesktop -nodisplay -r \"ImageDCT('$photo_upload_path','$processed_photo_output_path');exit\""; exec($command); #<6>stream processed photo to the client streamFile($processed_photo_output_path, $downloadFileName,"application/octet-stream"); } else{ echo "There was an error uploading the file to $photo_upload_path !"; } ?>
5.Matlab代码(实现DCT变换) [matlab code]
- function ImageDCT(input_img_path, output_img_path)
- %-----------------------------------------------------------------------------
- % @Author: ZhengHaibo zhb931706659@126.com
- % Android Tutorial : Server-Client Communication
- %------------------------------------------------------------------------------
- % INPUT:
- % input_img_path - input image path
- % output_img_path - output image path
- %------------------------------------------------------------------------------
- tic;
- if nargin < 2
- input_img_path =('./upload/test.jpg');
- output_img_path =('./output/test.jpg');
- end
- if(isempty(input_img_path))
- input_img_path =('./upload/test.jpg');
- end
- if(isempty(output_img_path))
- output_img_path =('./output/test.jpg');
- end
- % --------------------------------------------------------------------
- % Load an image
- % --------------------------------------------------------------------
- InputImg = imread(input_img_path);
- GrayInputImg=rgb2gray(InputImg);
- DCT_Result=dct2(GrayInputImg)*4;
- imwrite(uint8(DCT_Result), output_img_path,'Quality',100);
- toc
- end
function ImageDCT(input_img_path, output_img_path) %----------------------------------------------------------------------------- % @Author: ZhengHaibo zhb931706659@126.com % Android Tutorial : Server-Client Communication %------------------------------------------------------------------------------ % INPUT: % input_img_path - input image path % output_img_path - output image path %------------------------------------------------------------------------------ tic; if nargin < 2 input_img_path =('./upload/test.jpg'); output_img_path =('./output/test.jpg'); end if(isempty(input_img_path)) input_img_path =('./upload/test.jpg'); end if(isempty(output_img_path)) output_img_path =('./output/test.jpg'); end % -------------------------------------------------------------------- % Load an image % -------------------------------------------------------------------- InputImg = imread(input_img_path); GrayInputImg=rgb2gray(InputImg); DCT_Result=dct2(GrayInputImg)*4; imwrite(uint8(DCT_Result), output_img_path,'Quality',100); toc end
实验结果展示: [图]
Reference: [1]PHP学习之初:基本语法 http://blog.csdn.net/nuptboyzhb/article/details/7912483 [2]基于android和WAMP5的B/S模式的本机测试平台(android+web) http://blog.csdn.net/nuptboyzhb/article/details/7932234 [3]命令行方式执行matlab代码 :http://blog.csdn.net/nuptboyzhb/article/details/7943910 [4]Android图像处理系统1.4图像的锐化-边缘检测 :http://blog.csdn.net/nuptboyzhb/article/details/7926735 [5]斯坦福大学EE368实验室:http://www.stanford.edu/class/ee368/index.html
posted on 2013-02-20 15:15 ellisonDon 阅读(1495) 评论(0) 编辑 收藏 举报