Labview图像与移动端显示

Labview程序图像与移动端显示

引言:大家使用Labview进行图像处理绘图时候,不免会想更进一步,移植到移动端显示,无论是做科研,还是打比赛都有一定的帮助,下面将为大家阐述具体步骤。

一、Labview端处理

Labview是一款图形化编辑语言,目前科研上使用较多,因为其较为简单的操作手段,所以深受科研人员喜爱,不仅图像处理方便,还很容易进行一些硬件测试连接。本篇着重讲解Labview图像绘制以及如何实现交互效果。

1.通讯方式

本次实例以实际项目中为例,使用Labview接收Stm32数据,这里方便演示采用串口方式。

Labview与单片机通讯方式

2.数据处理(重点)

本次测试中,单片机的传输数据为:xxx,xxx,xxx…xxx,每行会发送25个数据,所以咱们只需要每次读取25个数据出来,再进行操作即可,这里由于涉及到持续读取操作,所以将数据处理放在While循环中。

在这里插入图片描述

数据处理我这里采用,每次把一行数据全部读完之后再进行操作,这里仅仅展示了5个数据的处理(也就是一行数据),这样子就提取出来了数据点。

在这里插入图片描述

提取出来数据点之后,可以根据自己的需要进行调试,这里我只展示了一个点的像素点绘制效果,分别设有三个颜色,对应不同压力情况下的颜色变化。

在这里插入图片描述

最后汇总到一个面板中,就可以实现Labview端的图像绘制效果。前面板展示图:

在这里插入图片描述

3.图像移植

想实现电脑端和移动端交互,这里有多种方式:其中企业上使用的一定是将数据传送到服务器中,然后移动端读取服务器数据,达到完美显示效果。如果使用服务器,这里Labview端可以采用Http通讯方式,完成需求。这里为了方便演示,我采用第二种方式,仅仅使用本地即可完成需求。

实现思路:将Labview端图像存储到电脑本地PNG(或JPG)文件中,然后还需要一个服务器端,不断读取这个文件里面的图像,将图片数据存储到本地数据库中,最后移动端读取数据库信息即可实现效果,不过存在500ms左右的延迟。

可能会有初学者感到疑惑,为什么不直接让移动端读取本地文件,非要借助数据库。这里我解释一下,我尝试之后,发现移动端并不能直接本地磁盘文件,我使用的是Android Studio,通过查询资料也发现微信小程序好像也不可以,必须要把图像先保存到项目路径下,才可以访问,这样操作肯定是不行的,因为我们本地文件中的图像是一直在随着Labview程序的跑动而改变的。

4.服务器端代码

既然需要服务器不断读取本地文件,并将图像转化成二进制存入到数据库中,这就涉及到IO处理,这里我采用Java语言进行该操作,只需要简单使用JDBC就可以完成该需求,后续如果想做完善的项目,可以使用Mybatis框架进行处理。本篇博客只是提供一种思路和解决方式,所以代码写的比较随意,以实现需求为主,请大家理性看待。

package ck.preparedStatement;
import java.io.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Timer;
import java.util.TimerTask;
/**
 * @author ck
 * 演示使用
 */
public class PrepareStatement {
    public static void main(String[] args) throws ClassNotFoundException, SQLException, IOException {
        Class.forName("com.mysql.cj.jdbc.Driver");

        //创建url,user,password
        String url = "jdbc:mysql://localhost:3306/picture";
        String user = "root";
        String password = "970125";

        Connection connection = DriverManager.getConnection(url, user, password);
        final FileInputStream[] fis = {null};
        final PreparedStatement[] ps = {null};
        Timer timer = new Timer();
       timer.schedule(new TimerTask(){
           @Override
           public void run() {

               try {
                   fis[0] = new FileInputStream(new File("D:\\Desktop\\png\\2.png"));
               } catch (FileNotFoundException e) {
                   e.printStackTrace();
               }

               String sql = "insert into photo (data) values (?)";
               try {
                    ps[0] = connection.prepareStatement(sql);
               } catch (SQLException e) {
                   e.printStackTrace();
               }
               try {
                   ps[0].setBinaryStream(1, fis[0], fis[0].available());
               } catch (SQLException e) {
                   e.printStackTrace();
               } catch (IOException e) {
                   e.printStackTrace();
               }
               int i = 0;
               try {
                   i = ps[0].executeUpdate();
               } catch (SQLException e) {
                   e.printStackTrace();
               }
               if (i > 0){
                   System.out.println("执行成功");
               }else{
                   System.out.println("失败");
               }

           }
       },0,500);
        ps[0].close();
        fis[0].close();
        connection.close();

    }
}

而在数据库表的设计也是十分简单。data字段采用bomb格式存储。我这里也是为了方便测试为主,选择的是直接讲二进制存入到数据库中,这种方式对于小内存的图像处理是没问题的,但是大内存的话还是会存在问题的。

在这里插入图片描述

5.移动端代码

移动端由于要读取数据库,所以也是需要对数据库进行索引,选用Android Studio也是为了方便,跟Java有着99%的相似度。不过多阐述。

package com.ck.picture;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.widget.ImageView;
import androidx.appcompat.app.AppCompatActivity;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class MainActivity extends AppCompatActivity {

    private static final String DB_URL = "jdbc:mysql://192.168.75.76:3306/picture";
    private static final String DB_USER = "root";
    private static final String DB_PASSWORD = "970125";

    private ImageView imageView;
    private int currentImageId = 3586; // Start with the first image ID

    private final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        imageView = findViewById(R.id.myImageView);

        // Schedule the task to load images periodically
        scheduledExecutorService.scheduleAtFixedRate(new LoadImageTask(), 0, 400, TimeUnit.MILLISECONDS);
    }

    private class LoadImageTask implements Runnable {
        @Override
        public void run() {
            try {
                Class.forName("com.mysql.jdbc.Driver");
                Connection connection = DriverManager.getConnection(DB_URL,DB_USER,DB_PASSWORD);
                String query = "SELECT data FROM photo WHERE id = ?";
                PreparedStatement preparedStatement = connection.prepareStatement(query);
                preparedStatement.setInt(1, currentImageId);

                ResultSet resultSet = preparedStatement.executeQuery();

                if (resultSet.next()) {
                    byte[] imageBytes = resultSet.getBytes("data");
                    final Bitmap bitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);

                    // Update UI on the main thread
                    new Handler(Looper.getMainLooper()).post(new Runnable() {
                        @Override
                        public void run() {
                            imageView.setImageBitmap(bitmap);
                        }
                    });

                    currentImageId++; // Move to the next image
                }

                resultSet.close();
                preparedStatement.close();
                connection.close();
            } catch (SQLException | ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        // Stop the scheduled task when the activity is destroyed
        scheduledExecutorService.shutdown();
    }
}

结语:至此项目需求就已经全部实现了。有需要的可以留言或者私信。

在这里插入图片描述

结语:至此项目需求就已经全部实现了。有需要的可以留言或者私信。

欢迎大家积极讨论学习。

  • 25
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值