基于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]

 

  1. publicclass ServerTask  extends AsyncTask<String, Integer , Void> 
  2.         { 
  3.             publicbyte[] dataToServer; 
  4.                      
  5.             //Task state 
  6.             privatefinalint UPLOADING_PHOTO_STATE  = 0
  7.             privatefinalint SERVER_PROC_STATE  = 1
  8.              
  9.             private ProgressDialog dialog; 
  10.             //upload photo to server 
  11.             HttpURLConnection uploadPhoto(FileInputStream fileInputStream) 
  12.             { 
  13.                  
  14.                 //final String serverFileName = "test"+ (int) Math.round(Math.random()*1000) + ".jpg";       
  15.                 final String serverFileName = "test.jpg"
  16.                 final String lineEnd = "\r\n"
  17.                 final String twoHyphens = "--"
  18.                 final String boundary = "*****"
  19.                 Log.e("msg","begin HttpURLConnection......"); 
  20.                 try 
  21.                 { 
  22.                     URL url = new URL(SERVERURL); 
  23.                     // Open a HTTP connection to the URL 
  24.                     final HttpURLConnection conn = (HttpURLConnection)url.openConnection(); 
  25.                     // Allow Inputs 
  26.                     conn.setDoInput(true);               
  27.                     // Allow Outputs 
  28.                     conn.setDoOutput(true);              
  29.                     // Don't use a cached copy. 
  30.                     conn.setUseCaches(false); 
  31.                      
  32.                     // Use a post method. 
  33.                     conn.setRequestMethod("POST"); 
  34.                     conn.setRequestProperty("Connection", "Keep-Alive"); 
  35.                     conn.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundary); 
  36.                      
  37.                     DataOutputStream dos = new DataOutputStream( conn.getOutputStream() ); 
  38.                      
  39.                     dos.writeBytes(twoHyphens + boundary + lineEnd); 
  40.                     dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" + serverFileName +"\"" + lineEnd); 
  41.                     dos.writeBytes(lineEnd); 
  42.  
  43.                     // create a buffer of maximum size 
  44.                     int bytesAvailable = fileInputStream.available(); 
  45.                     int maxBufferSize = 1024
  46.                     int bufferSize = Math.min(bytesAvailable, maxBufferSize); 
  47.                     byte[] buffer = newbyte[bufferSize]; 
  48.                      
  49.                     // read file and write it into form... 
  50.                     int bytesRead = fileInputStream.read(buffer, 0, bufferSize); 
  51.                      
  52.                     while (bytesRead > 0
  53.                     { 
  54.                         dos.write(buffer, 0, bufferSize); 
  55.                         bytesAvailable = fileInputStream.available(); 
  56.                         bufferSize = Math.min(bytesAvailable, maxBufferSize); 
  57.                         bytesRead = fileInputStream.read(buffer, 0, bufferSize); 
  58.                     } 
  59.                      
  60.                     // send multipart form data after file data... 
  61.                     dos.writeBytes(lineEnd); 
  62.                     dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd); 
  63.                     publishProgress(SERVER_PROC_STATE); 
  64.                     // close streams 
  65.                     fileInputStream.close(); 
  66.                     dos.flush(); 
  67.                     Log.e("msg","upload finished!"); 
  68.                     return conn; 
  69.                 } 
  70.                 catch (MalformedURLException ex){ 
  71.                     Log.e(TAG, "error: " + ex.getMessage(), ex); 
  72.                     returnnull
  73.                 } 
  74.                 catch (IOException ioe){ 
  75.                     Log.e(TAG, "error: " + ioe.getMessage(), ioe); 
  76.                     returnnull
  77.                 } 
  78.             } 
  79.              
  80.             //get image result from server and display it in result view 
  81.             void getResultImage(HttpURLConnection conn){         
  82.                 // retrieve the response from server 
  83.                 InputStream is; 
  84.                 try
  85.                     is = conn.getInputStream(); 
  86.                     //get result image from server 
  87.                     resultForWebImage = BitmapFactory.decodeStream(is); 
  88.                     is.close();              
  89.                     IsShowingResult = true
  90.                     Log.d("msg","download finished!"); 
  91.                 } catch (IOException e) { 
  92.                     Log.e(TAG,"getResultImage:"+e.toString()); 
  93.                     e.printStackTrace(); 
  94.                 } 
  95.             } 
  96.             //Main code for processing image algorithm on the server 
  97.             void processImage(String inputImageFilePath){            
  98.                 publishProgress(UPLOADING_PHOTO_STATE); 
  99.                 File inputFile = new File(inputImageFilePath); 
  100.                 try
  101.                      
  102.                     //create file stream for captured image file 
  103.                     FileInputStream fileInputStream  = new FileInputStream(inputFile); 
  104.                      
  105.                     //upload photo 
  106.                     final HttpURLConnection  conn = uploadPhoto(fileInputStream); 
  107.                      
  108.                     //get processed photo from server 
  109.                     if (conn != null){ 
  110.                       getResultImage(conn); 
  111.                     //String download="http://10.10.145.154/EE368_Android_Tutorial3_Server/computeSIFTOnSCIEN.php"; 
  112.                      
  113.                     } 
  114.                     fileInputStream.close(); 
  115.                 } 
  116.                 catch (FileNotFoundException ex){ 
  117.                     Log.e(TAG, "processImage"+ex.toString()); 
  118.                 } 
  119.                 catch (IOException ex){ 
  120.                     Log.e(TAG, "processImage"+ex.toString()); 
  121.                 } 
  122.             } 
  123.              
  124.             public ServerTask() { 
  125.                 dialog = new ProgressDialog(SystemMain.this); 
  126.             }        
  127.              
  128.             protectedvoid onPreExecute() { 
  129.                 this.dialog.setMessage("Photo captured"); 
  130.                 this.dialog.show(); 
  131.             } 
  132.             @Override 
  133.             protected Void doInBackground(String... params) {           //background operation  
  134.                 String uploadFilePath = params[0]; 
  135.                 processImage(uploadFilePath); 
  136.                 //release camera when previous image is processed 
  137.                 mCameraReadyFlag = true;  
  138.                 returnnull
  139.             }        
  140.             //progress update, display dialogs 
  141.             @Override 
  142.              protectedvoid onProgressUpdate(Integer... progress) { 
  143.                  if(progress[0] == UPLOADING_PHOTO_STATE){ 
  144.                      dialog.setMessage("Uploading"); 
  145.                      dialog.show(); 
  146.                  } 
  147.                  elseif (progress[0] == SERVER_PROC_STATE){ 
  148.                        if (dialog.isShowing()) { 
  149.                            dialog.dismiss(); 
  150.                        }              
  151.                      dialog.setMessage("Processing"); 
  152.                      dialog.show(); 
  153.                  }            
  154.              }       
  155.                @Override 
  156.                protectedvoid onPostExecute(Void param) { 
  157.                    if (dialog.isShowing()) { 
  158.                        dialog.dismiss(); 
  159.                         
  160.                        if(IsShowingResult){ 
  161.                            ShowImage(resultForWebImage, 2); 
  162.                            IsShowingResult=false
  163.                        } 
  164.                    } 
  165.                } 
  166.         } 
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]

  1. sendBtnListener=new OnClickListener() { 
  2.      
  3.     @Override 
  4.     publicvoid onClick(View v) { 
  5.         // TODO Auto-generated method stub 
  6.                
  7.         if(myBitmap!=null){ 
  8.             mClientForWeb.compressByteImage(myBitmap, 75);; 
  9.             ServerTask task = new ServerTask(); 
  10.                 Log.e("msg","new ServerTask finished!"); 
  11.                 task.execute(Environment.getExternalStorageDirectory().toString() +mClientForWeb.INPUT_IMG_FILENAME); 
  12.         } 
  13.     } 
  14. }; 
		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]

 

  1. <?php 
  2. #------------------------------------------------------------------------------- 
  3. # EE368 Digital Image Processing 
  4. # Android Tutorial #3: Server-Client Interaction Example for Image Processing 
  5. # Author: Derek Pang (dcypang@stanford.edu), David Chen (dmchen@stanford.edu) 
  6. #------------------------------------------------------------------------------ 
  7.  
  8. #functionfor streaming file to client 
  9. function streamFile($location, $filename, $mimeType='application/octet-stream'
  10. { if(!file_exists($location)) 
  11.   { header ("HTTP/1.0 404 Not Found"); 
  12.     return
  13.   } 
  14.    
  15.   $size=filesize($location); 
  16.   $time=date('r',filemtime($location)); 
  17.   #html response header 
  18.   header('Content-Description: File Transfer');  
  19.   header("Content-Type: $mimeType");  
  20.   header('Cache-Control: public, must-revalidate, max-age=0'); 
  21.   header('Pragma: no-cache');   
  22.   header('Accept-Ranges: bytes'); 
  23.   header('Content-Length:'.($size)); 
  24.   header("Content-Disposition: inline; filename=$filename"); 
  25.   header("Content-Transfer-Encoding: binary\n"); 
  26.   header("Last-Modified: $time"); 
  27.   header('Connection: close');       
  28.  
  29.   ob_clean(); 
  30.   flush(); 
  31.   readfile($location); 
  32.      
  33.  
  34. #********************************************************** 
  35. #Main script 
  36. #********************************************************** 
  37.  
  38. #<1>set target path for storing photo uploads on the server 
  39. $photo_upload_path = "./upload/"
  40. $photo_upload_path = $photo_upload_path. basename( $_FILES['uploadedfile']['name']);  
  41. #<2>set target path for storing result on the server 
  42. $processed_photo_output_path = "./output/processed_"
  43. $processed_photo_output_path = $processed_photo_output_path. basename( $_FILES['uploadedfile']['name']);  
  44. $downloadFileName = 'processed_' . basename( $_FILES['uploadedfile']['name']);  
  45.  
  46. #<3>modify maximum allowable file size to 10MB and timeout to 300s 
  47. ini_set('upload_max_filesize', '10M');   
  48. ini_set('post_max_size', '10M');   
  49. ini_set('max_input_time', 300);   
  50. ini_set('max_execution_time', 300);   
  51.  
  52. #<4>Get and stored uploaded photos on the server 
  53. if(copy($_FILES['uploadedfile']['tmp_name'], $photo_upload_path)) { 
  54.      
  55.     #<5> execute matlab image processing algorithm 
  56.     #example: Compute and display SIFT features using VLFeat and Matlab 
  57.     $command = "matlab -nojvm -nodesktop -nodisplay -r \"ImageDCT('$photo_upload_path','$processed_photo_output_path');exit\""
  58.     exec($command); 
  59.     #<6>stream processed photo to the client 
  60.     streamFile($processed_photo_output_path, $downloadFileName,"application/octet-stream"); 
  61. } else
  62.     echo"There was an error uploading the file to $photo_upload_path !"
  63.  
  64. ?> 
<?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]

 

  1. function ImageDCT(input_img_path, output_img_path) 
  2. %----------------------------------------------------------------------------- 
  3. % @Author: ZhengHaibo zhb931706659@126.com 
  4. % Android Tutorial : Server-Client Communication 
  5. %------------------------------------------------------------------------------ 
  6. % INPUT: 
  7. % input_img_path    - input image path 
  8. % output_img_path   - output image path 
  9. %------------------------------------------------------------------------------ 
  10. tic; 
  11. if nargin < 2 
  12.     input_img_path =('./upload/test.jpg'); 
  13.     output_img_path =('./output/test.jpg'); 
  14. end 
  15. if(isempty(input_img_path)) 
  16.     input_img_path =('./upload/test.jpg'); 
  17. end 
  18. if(isempty(output_img_path)) 
  19.     output_img_path =('./output/test.jpg'); 
  20. end 
  21. % -------------------------------------------------------------------- 
  22. %                                                        Load an image 
  23. % -------------------------------------------------------------------- 
  24. InputImg = imread(input_img_path); 
  25. GrayInputImg=rgb2gray(InputImg); 
  26. DCT_Result=dct2(GrayInputImg)*4; 
  27. imwrite(uint8(DCT_Result), output_img_path,'Quality',100); 
  28. toc 
  29. 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编辑  收藏  举报

导航