栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

android 实时图像传输实现

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

android 实时图像传输实现

android 实时图像传输实现(java)

本质就是图像传输,在次基础上的扩展。

实现原理

其实就是图像一帧一帧的传输,一直下去就能达到实时图像传输的效果了。

具体实现
socket对象调用 getInputStream()方法获得一个输入流 inputStream,同时使用 FileOutputStream(file)方法创建一个文件输出流用来保存图片数据其中 file为图片的绝对路径,之后对 inputStream不断调用 read ()方法进行数据读取,并且将读取的数据通过输出流的 write()方法写入本地,本地则是通过handle来获得的图片并通过BitmapFactory.decodeFile函数来得到一个Bitmap图像,最后通过进行相应比例的放大,通过 paint(画笔工具)在canvas(画布)上绘制并提交画布显示到 SurfaceView上。

涉及知识

TCP 、socket ,java文件流,android基础、SurfaceView

参考代码

TCP接受部分函数 image_transmission()
这里只是贴了图像接受部分修改的函数,并不是具体实现的文件,具体实现可参考[java图像传输]。(https://blog.csdn.net/NS_ice/article/details/124306479?spm=1001.2014.3001.5502)

// 图像传输客户端程序  这个服务端接受线程中使用的函数
    private void image_transmission() throws IOException {
            File file = new File("data/data/com.example.uidemo4/1.jpg");
            //com.example.uidemo4 是安卓软件的包名  这个文件夹下的文件 app才有权限进行读取和修改
        if (!file.exists()) {                //exists()  判断是否存在,存在返回true
            System.out.println("建立此文件");
            boolean a= false;                 //不存在就创建一个,空文件
            try {
                a = file.createNewFile();  	//文件不存在且新建成功会返回true
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (a) {
                System.out.println(file.toString().trim());
            }
        }
        inputStream = socket.getInputStream();
        FileOutputStream fos = null;
        byte[] temByte = new byte[2048]; // 读取缓冲数组
        byte[] preByte = new byte[15];	//数据头
        byte[] sizeByte = new byte[5];	//图片大小
        byte[] endByte = new byte[3];	// 数据尾
        int all = 0;// 已读取的文件总长度
        while (flag) {
            int len;
            len = inputStream.read(preByte);//读取数据头 
            String readTextString = new String(preByte, "UTF-8");
          	   if (readTextString.equals("start")) {
//                  System.out.println("开始接收图像");
                	len = inputStream.read(sizeByte); //读取图片大小
                	String a = new String(sizeByte, "UTF-8");
                	int length = Integer.parseInt(a);
//                  System.out.println("图片大小为:" + a);
               		fos = new FileOutputStream(file);

                for (all = 0;all 

注意这里的接受,发送端需要根据接受端的接受顺序来发送数据
发送顺序为: start (数据头字符串)+ 图片大小(字符串)+ 图片文件 + end (数据结束尾)
在图片大小前和数据头前还可以加入字符串数据,图片文件尾后和end前也可以加入字符串数据,接收方法和数据头尾类似。

直接复制代码会报错:

  1. File file = new File(“data/data/com.example.uidemo4/1.jpg”); 路径问题
  2. inputStream = socket.getInputStream(); 需要自己定义全局变量
  3. .sendEmptyMessage(MyHandler.READ_DATA); 需要自己new 一个MyHandler对象。
MyHandler handler = new MyHandler(MainActivity.this ,mSurfaceholder);

此外 surfaceholder需要通过xml中的控件SurfaceView来获取。

		//全局变量
    	private SurfaceView mCameraView;                //surfaceView
   		private SurfaceHolder mSurfaceholder;

		//onCreate函数中通过id获取控件
        mSurfaceView =findViewById(R.id.surface_view);
        mSurfaceholder = mSurfaceView .getHolder();

xml文件 布局文件
大小宽度布局自己根据需求来设置

    
handle 消息处理机制

用于更新ui界面,详情可以去网上搜具体功能(资源很多),这里只简单介绍使用。

public class MyHandler extends Handler
{
	public static final int READ_DATA = 9;  //数字没有具体意义就是为了区分消息的作用,用于下方switch判断。
	private Rect mSrcRect, mDestRect;
	private SurfaceHolder surfaceholder;
	//private SurfaceView surfaceView;
    private Paint paint;		//画笔工具,理解就好,没有特别需要注意的
    private Bitmap bitmap;		// 图片文件,用户绘制
    private Canvas canvas;		//画布工具,能用就行
    //  构造方法  可根据需求自己创建
    MyHandler(Context context, SurfaceHolder surfaceholder)
    {
        this.context = context;
        this.surfaceholder = surfaceholder;
    }
    
 @Override
    public void handleMessage(@NonNull Message msg)
    {

        switch (msg.what)
        {
            case READ_DATA:
              try {
                    canvas = surfaceholder.lockCanvas();//锁定画布
                    if(canvas!=null){
//                        System.out.println("开始绘制");
                        paint = new Paint();
                        paint.setAntiAlias(true);
                        paint.setStyle(Paint.Style.STROKE);
                           
//                        canvas.drawColor(Color.WHITE);   //绘制背景
                        bitmap = BitmapFactory.decodeFile("data/data/com.example.uidemo4/1.jpg");  // 获取bitmap
                        // 文件路径就是上面接受端保存路径的位置
                        mSrcRect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
                        mDestRect = new Rect(0, 0, canvas.getWidth(), canvas.getHeight());
						//这两句是用来获取图片大小和画布大小,在下面绘制函数中用到的参数,使用这个可以让图片填充到画布相同大小
						//这里的画布大小,其实就是你xml文件中SurfaceHolder的大小
                        canvas.drawBitmap(bitmap, mSrcRect, mDestRect, paint); //执行绘制操作
//                        canvas.drawBitmap(bitmap, 0, 0, paint); //不调节图像与画布比例,直接画原图
                    }
                }catch (Exception e){

                }finally {
                    if (canvas != null) {
                        surfaceholder.unlockCanvasAndPost(canvas);//解锁并提交画布
//                        System.out.println("绘制完成");
                        if (bitmap!=null){                
                        bitmap.recycle();}
               			 break; 
                        }
   			 }
    }

以上就是图像实时传输的主要实现代码,并没有把完整工程文件代码贴出来,显得冗余,主要是提供一个思路和核心代码实现吧,代码中注释还是比较详细的,有不理解的可以网上查或者评论区留言,看到就会回复的,觉得还不错的话可以高抬贵手点个赞。有需要话可以整个手把手教程。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/820809.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号