Linux环境下,Java调用Matlab画图

在Java Web开发过程中,经常会遇到需要将数据分析的结果很直观的展现给用户,这就要用到数据统计图(柱形图、饼图、折线图),对于一些简单的统计图,可以推荐使用jfreechart,是第三方开源的框架。但是对于复杂的图形,使用这些框架就不太合适了,比如

要求展现的图比较复杂,具体需求这边不阐述,如果使用Matlab作图,就很方便,但是在使用的过程中会遇到很多的坑,因为这个作图功能,让我将生产服务器从Linux到Windows server 2012再到Linux,最后换为Linux是因为在Windows服务器上生成的图片全是黑的,没要找到有效的解决办法。

Matlab是专业的数学软件,主要包括MATLAB和Simulink两大部分。本文主要讲述在Java程序中如何使用Matlab程序、Linux中安装MCR(Matlab Compiler Runtime,Matlab运行时环境)以及在使用过程中遇到的一些问题的解决办法,并以R2016a版本的Matlab为例,以此分享给对Matlab感兴趣的同学。

一、编写Matlab脚本

举个简单的例子,利用Matlab画一个正弦函数(y=sin(x))的图像。

function plotSin()
x=-3.14:0.01:3.14;
y=sin(x);
plot(x,y);
ylabel('y=sin(x)图像');
title('Java调用Matlab作正弦函数图像');

保存,并执行函数脚本:

然后稍微修改下plotSin函数:

function plotSin(x, savePath)
%savePath图片保存地址
%x=-3.14:0.01:3.14;
 y=sin(x);
plot(x,y);
ylabel('y=sin(x)图像');
title('Java调用Matlab作正弦函数图像');
set(gcf,'visible','off')
set(gcf, 'PaperPositionMode', 'manual');
set(gcf, 'PaperUnits', 'points');
set(gcf, 'PaperPosition', [0 0 500 600]);
saveas(gcf,savePath) ;

下面将脚本plotSin函数编译并打包成Jar包,值得注意的是,打包编译的 JDK版本不能超过1.7,所以事先检查环境变量,如果是1.8以上的,请修改成1.7或以下版本,编译后是可以在1.7版本以上的环境下执行的。在Matlab命令窗口输入deploytool,并回车:

选择Library Compile,在弹出的窗口按如下步骤操作

1:选择Java Package

2:输入包名(Library name);

3:输入类路径(Namespase);

4:输入类名(Class namejava类,在后边java代码中会用);

5:点击加号按钮,添加刚才的plotSin.m文件;

6:点击Package打包。

打包需要一定过程,接下来就是耐心的等待了。

打包成功后在for_redistribution_files_only路径下找到plot.jar,以及在Matlab安装目录R2016a\toolbox\javabuilder\jar 找到javabuilder.jar。

二、如何使用

将上述两个包引入项目中,接下来就是在Java程序中使用了,直接上代码:

package com.seage;

import com.mathworks.toolbox.javabuilder.MWArray;
import com.mathworks.toolbox.javabuilder.MWClassID;
import com.mathworks.toolbox.javabuilder.MWComplexity;
import com.mathworks.toolbox.javabuilder.MWNumericArray;
import com.mathworks.toolbox.javabuilder.internal.MWComponentInstance;
import com.seage.plotsin.PlotSin;

/**
 * Title: PlotSinMain
 * 描述:
 * @author wangzb
 * @Date 2018-8-21 上午9:32:15
 */
public class PlotSinMain {
   /**
	 * 画图
	 * @param savePath 图片保存地址
	 */
    private static voit plot(String savePath){
	    PlotSin plot = null;//打包是定义的类
	    MWNumericArray x = null; // 存放x值的数组
	     try{
	    	 int size = (int) (6.28/0.01 + 1);
	    	 /*
	    	  * 初始化数组,定义一个一维数组,其中:
	    	  * MWClassID.DOUBLE定义数据类型为double
	    	  * MWComplexity.REAL定义数据为实数
	    	  */
	    	 int[] dims = {1,size};
              x = MWNumericArray.newInstance(dims, MWClassID.DOUBLE,MWComplexity.REAL);
	    	 int index = 1;
	    	 for (double i=-3.14;i<=3.14;i=i+0.01){
	    		 x.set(index++,i);
	    	 }
	    	 plot = new PlotSin();
	    	 String savePath = "E:\\seage\\1.png";
	    	 //调用画图函数
	    	 plot.plotSin(x,savePath);
	    	 plot.waitForFigures();
	     } catch(Exception e){
	    	 e.printStackTrace();
	     } finally{
	    	 //关闭资源
	    	 dispose(plot, x);
	     }
   }
    /**
      * 关闭资源
      * @param plot 画图对象
      * @param mwArrays 画图参数数组对象
      */
    public static void dispose(MWComponentInstance plot, MWArray... mwArrays){
        if(plot!=null){
            plot.dispose();
        }
        for(MWArray mwArray : mwArrays){
            if(mwArray!=null){
                MWArray.disposeArray(mwArray);
            }
        }
    }


    public static void main(String[] args) {
		 String savePath = "E:\\seage\\1.png";
		 plot(savePath);
	}
}

使用起来并不难,但是实际生产中,业务量比较复杂,往往需要生成图片不止一张,甚至在并发的情况下,需要同时生成几百张图片,所以必须注意以下两点:

1、在生成每一张图片后都需要调用dispose(plot, x)方法关流,否则会消耗大量内存,浪费大量的资源;

2、int[] dims = {row,col};其中行row以及col避免出现负数或者封装Intger的null值,否则会导致tomcat内存溢出,造成tomcat死机。

最后,将上述代码打包成可执行的jar文件,以便在已成功安装MCR环境下的Linux系统中测试。

三、Linux中使用Matlab

众所周知,在企业级项目中,大部分系统还是使用的是Linux,单纯的在Windows系统中正确使用了Matlab是完全不够的,Matlab提供了MCR,可用于在未安装 MATLAB 的计算机上执行编译后的 MATLAB 应用程序或组件。执行如下命令下载MCR安装包:

1:下载安装包

[root@EM0103170701 matlab]# wget http://ssd.mathworks.com/supportfiles/downloads/R2016a/deployment_files/R2016a/installers/glnxa64/MCR_R2016a_glnxa64_installer.zip

2:解压安装包

[root@EM0103170701 matlab]# unzip MCR_R2016a_glnxa64_installer zip -d MCR_R2016a_glnxa64_installer

3:进入解压后的目录

[root@EM0103170701 matlab]# cd MCR_R2016a_glnxa64_installer

4:安装

[root@EM0103170701 matlab]#  ./install -mode silent -agreeToLicense  yes

当出现下面语句,表示安装成功。

Exitingwith status 0
End – Successful.
Finished

5、配置环境变量

export MCR_HOME=/usr/local/MATLAB/MATLAB_Runtime
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MCR_HOME/v901/runtime/glnxa64:$MCR_HOME/v901/sys/os/glnxa64:$MCR_HOME/v901/sys/java/jre/glnxa64/jre/lib/amd64/headless:$MCR_HOME/v901/sys/java/jre/glnxa64/jre/lib/amd64/server:$MCR_HOME/v901/sys/java/jre/glnxa64/jre/lib/amd64

6、测试

将第二步最后打包的jar文件拷贝到linux服务器,运行如下命令

[root@EM0103170701 matlab]# jar -jar plotsin.jar

如果执行成功则万事大吉,下面将列出我在使用过程中出现的错误,以及解决办法。

1、无法加载libmwosgserver.so

Can't load   '/usr/local/MATLAB/MATLAB_Runtime/v901/bin/glnxa64/libmwosgserver.so'

在环境变量的LD_LIBRARY_PATH下引入: 

$MCR_HOME/v901/bin/glnxa64:$MCR_HOME/v901/sys/opengl/lib/glnxa64

2、在tomcat下运行时出现异常NoClassDefFoundError MWClassID.class,这种错误一般原因很多,很难找到真正的原因,类明显是在的,但就是无法找到,实在让人头疼。这个错误需要区别于ClassNotfoundException,事实上这两个错误是完全不同的,NoClassDefFoundError是在运行时,根据你提供的类名,在classpath中找不到对应的类进行加载,而ClassNotFoundException是在编译的时候在classpath中找不到对应的类而发生的错误。

最后发现是因为javabuilder.jar在tomcat下,其他用户组没有任何权限,进入项目的lib路径下,执行如下命令:

chmod a+r *

重启tomcat,再次执行,然后奇迹般的好了。

3、在Linux系统中生成的图片出现中文乱码,一开始我以为是Matlab程序编码的问题,在网上找了很多办法去改变Matlab的编码,但都没有用,最终发现是Linux系统中没有安装中文支持,使用下面命令安装中文支持,问题解决。

yum -y groupinstall chinese-support

猜你喜欢

转载自blog.csdn.net/u012105931/article/details/81952672
今日推荐