鸿蒙开发实战-手写一个Openharmony投屏工具

实战手写一个Openharmony投屏工具,实现代码分享如下:

java
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class ImageFrame extends JFrame {

    private BufferedImage originalImage;
    private final String imagePath = System.getProperty("user.dir") + File.separator + "scr.jpeg"; // 图片文件的路径
    private final double aspectRatio = 720.0 / 1280.0; // 定义比例
    private ImagePanel imagePanel;
    private long pressTime; // 用于记录鼠标按下的时间
    private int initWidth = 517;  //初始窗口宽
    private int initHeight = 908;   //初始窗口高

    public ImageFrame() {
        setTitle("OHScrcpy(by zhonghongfa)");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // setLocationRelativeTo(null);
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        int screenWidth = screenSize.width;
        int screenHeight = screenSize.height;
        // 计算窗体在屏幕右侧的新位置
        int x = screenWidth - initWidth - 50;
        int y = 50; // 如果希望窗体垂直居中
        // 设置窗体的新位置
        setLocation(x, y);

        loadImage();
        imagePanel = new ImagePanel();
        add(imagePanel);
        setIconImage();

        addComponentListener(new ComponentAdapter() {
            public void componentResized(ComponentEvent e) {
                maintainAspectRatio();
            }
        });

        imagePanel.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                pressTime = System.currentTimeMillis(); // 记录鼠标按下的时间
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                long releaseTime = System.currentTimeMillis(); // 记录鼠标释放的时间
                double scaleX = (double) originalImage.getWidth() / imagePanel.getWidth();
                double scaleY = (double) originalImage.getHeight() / imagePanel.getHeight();
                int realX = (int) (e.getX() * scaleX);
                int realY = (int) (e.getY() * scaleY);
                if (releaseTime - pressTime > 500) { // 如果按下时间超过500毫秒,则认为是长按
                    System.out.println("Real Long pressed coordinates: (" + realX + ", " + realY + ")");
                    executeCommand(String.format("hdc shell uitest uiInput longClick %d %d", realX, realY));
                }else{
                    System.out.println("Real clicked coordinates: (" + realX + ", " + realY + ")");
                    // 构建并执行命令
                    executeCommand(String.format("hdc shell uitest uiInput click %d %d", realX, realY));
                }
            }
        });

        setSize(initWidth, initHeight); // 设置初始窗口大小
        new Timer(100, e -> updateImageAndReload()).start();
    }

    private void setIconImage() {
        try {
            BufferedImage iconImage = ImageIO.read(getClass().getResource("/OHScrcpy.png")); // 注意路径前的斜杠
            setIconImage(iconImage);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void loadImage() {
        try {
            File imageFile = new File(imagePath);
            if (imageFile.exists()) {
                originalImage = ImageIO.read(imageFile);
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    private void executeCommand(String command) {
        try {
            System.out.println("Executing command: " + command);
            Process process = Runtime.getRuntime().exec("cmd.exe /c " + command);
            process.waitFor();
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void updateImage() {
        try {
            // 执行外部命令更新图片
            String[] cmd = {
                    "cmd.exe",
                    "/c",
                    "hdc shell rm -rf /data/local/tmp/scr.jpeg & hdc shell snapshot_display -f /data/local/tmp/scr.jpeg & hdc file recv  /data/local/tmp/scr.jpeg"
            };
            Process p = Runtime.getRuntime().exec(cmd);
            p.waitFor(); // 等待命令执行完成

        } catch (IOException | InterruptedException ex) {
            ex.printStackTrace();
        }
    }

    private void updateImageAndReload() {
        updateImage();
        loadImage();
        imagePanel.repaint();
    }

    private void maintainAspectRatio() {
        Rectangle bounds = this.getBounds();
        int width = bounds.width;
        int height = (int) (width / aspectRatio);
        if (height != bounds.height) {
            this.setSize(width, height);
        }
    }

    // JPanel 的子类用于绘制图像
    private class ImagePanel extends JPanel {
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (originalImage != null) {
                g.drawImage(originalImage, 0, 0, getWidth(), getHeight(), this); // 动态调整图片大小
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new ImageFrame().setVisible(true));
    }
}


运行效果如下

Openharmony投屏工具_Java

485f48c927688f7ba739dc1871e0214e.jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/410814.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一篇文章告诉你ELK Stack是什么

目录 ELK Stack简介 ELK Stack优点 ELK Stack组成 Elasticsearch Elasticsearch简介 Elasticsearch主要特点 Elasticsearch核心概念 Elasticsearch的配置 Logstash Logstash简介 Logstash过滤器之grok正则匹配 Logstash过滤器之mutate数据修改 Logstash过滤器之Ge…

如何快速将每个图片做二维码?批量生成图片码的步骤

现在很多商品的包装上扫码都会展现出物品的图片信息,每个物品都会有单独的一张物品信息图片。那么当导出一批图片后,如何快速将每张图片单独生成一个二维码来使用呢?本文小编将通过图文内容给大家讲解一下图片二维码生成器的批量建码功能该如…

automatic_mine_sweeper —— A project review to improve myself

1. How to understand the whole structure of the project? 1.Cbutton.h 和 Cbutton.cpp文件: Cbutton.h文件- // Cbutton.h : main header file for the CBUTTON application //#if !defined(AFX_CBUTTON_H__240DD99D_BEDE_49BD_A960_3268C3644816__INCLUDED_…

Python实用技巧:处理JSON文件写入换行问题

Python实用技巧:处理JSON文件写入换行问题 🌈 个人主页:高斯小哥 🔥 高质量专栏:Matplotlib之旅:零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程 👈 希望得到您的订阅…

05 Flink 的 WordCount

前言 本文对应于 spark 系列的 Spark 的 WordCount 这里主要是 从宏观上面来看一下 flink 这边的几个角色, 以及其调度的整个流程 一个宏观 大局上的任务的处理, 执行 基于 一个本地的 flink 集群 测试用例 /*** com.hx.test.Test01WordCount** author Jerry.X.He* ver…

架构设计:流式处理与实时计算

引言 随着大数据技术的不断发展,流式处理和实时计算在各行各业中变得越来越重要。那么什么是流式处理呢?我们又该怎么使用它?流式处理允许我们对数据流进行实时分析和处理,而实时计算则使我们能够以低延迟和高吞吐量处理数据。本…

Bert基础(四)--解码器(上)

1 理解解码器 假设我们想把英语句子I am good(原句)翻译成法语句子Je vais bien(目标句)。首先,将原句I am good送入编码器,使编码器学习原句,并计算特征值。在前文中,我们学习了编…

4.测试教程 - 用例篇

文章目录 1.测试用例的基本要素2.测试用例的给我们带来的好处3.测试用例的设计方法3.1基于需求进行测试用例的设计3.1.1功能需求测试分析3.1.2非功能需求测试分析 3.2具体的设计方法3.2.1等价类3.2.2边界值3.2.3错误猜测法3.2.4判定表3.2.5场景设计法3.2.6因果图3.2.7因果图的需…

c++:vector的相关oj题(136. 只出现一次的数字、118. 杨辉三角、26. 删除有序数组中的重复项、JZ39 数组中出现次数超过一半的数字)

文章目录 1. 136. 只出现一次的数字题目详情代码(直接来异或)思路 2. 118. 杨辉三角题目详情代码1思路代码2思路2 3. 26. 删除有序数组中的重复项题目详情代码思路 4. JZ39 数组中出现次数超过一半的数字题目详情代码1(暴力)思路1代码2&#…

A Visual Guide to Mamba and State Space Models

用于语言建模的 Transformers 的替代方案 Transformer 架构一直是大型语言模型 (LLMs) 成功的主要组成部分。它已被用于当今几乎所有LLMs正在使用的产品,从 Mistral 等开源模型到 ChatGPT 等闭源模型。 为了进一步改进LLMs,开发…

【HarmonyOS】鸿蒙开发之Stage模型-基本概念——第4.1章

Stage模型-基本概念 名词解释 AbilityStage:应用组件的“舞台“ UIAbility:包含UI界面的应用组件,是系统调度的基本单元 WindowStage:组件内窗口的“舞台“ Window:用来绘制UI页面的窗口 HAP:Harmony Ability Package(鸿蒙能力类型的包) HSP:Harmony Sh…

【算法 - 动态规划】找零钱问题Ⅰ

在前面的动态规划系列文章中,关于如何对递归进行分析的四种基本模型都介绍完了,再来回顾一下: 从左到右模型 :arr[index ...] 从 index 之前的不用考虑,只考虑后面的该如何选择 。范围尝试模型 :思考 [L ,…

C++——二叉搜索树

二叉搜索树 二叉搜索树: 又为搜索二叉树,一般具有以下的性质 若它的左子树不为空,则左子树上所有的节点的值都小于父亲节点若它的右子树不为空,则右子树上所有的节点的值都大于父亲节点它的左右子树也都为二叉搜索树 二叉搜索树…

Vue前端实现一个本地消息队列(MQ), 让消息延迟消费或者做缓存

MQ功能实现的具体代码(TsMQ.ts): import { v4 as uuidx } from uuid;import emitter from /utils/mittclass Message {// 过期时间,0表示马上就消费exp: number;// 消费标识,避免重复消费tag : string;// 消息体body : any;constructor( exp…

Docker基础篇(六) dockerfile体系结构语法

FROM:基础镜像,当前新镜像是基于哪个镜像的 MAINTAINER :镜像维护者的姓名和邮箱地址 RUN:容器构建时需要运行的命令 EXPOSE :当前容器对外暴露出的端口号 WORKDIR:指定在创建容器后,终端默认登…

python中的类与对象(1)

目录 一. 引子:模板 二. 面向过程与面向对象 (1)面向过程编程 (2)面向对象编程 三. 对象与类 (1)对象 (2)类 四. 面向对象程序设计的特点:封装&#…

daydayEXP: 支持自定义Poc文件的图形化漏洞利用工具

daydayEXP: 支持自定义Poc文件的图形化漏洞利用工具 基于java fx写的一款支持加载自定义poc文件的、可扩展的的图形化渗透测试框架。支持批量漏洞扫描、漏洞利用、结果导出等功能。 使用 经过测试,项目可在jdk8环境下正常使用。jdk11因为缺少一些必要的组件,所以jdk11版本工…

sqli-labs第46关

注:说明借鉴(现阶段水平不够,只能靠借鉴来完成本次作业,若侵权,必删) 基于Sqli-Labs靶场的SQL注入-46~53关_sqli-lab less46-CSDN博客 SQL-Labs46关order by注入姿势-CSDN博客 一、首先需要sql-labs的环…

计算机设计大赛 深度学习图像风格迁移

文章目录 0 前言1 VGG网络2 风格迁移3 内容损失4 风格损失5 主代码实现6 迁移模型实现7 效果展示8 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 深度学习图像风格迁移 - opencv python 该项目较为新颖,适合作为竞赛课题…

StringBuffer StringBuilder

String 为什么StringBuilder是线程不安全的?StringBuffer是线程安全的? - Jacian - 博客园 (cnblogs.com) StringBuilder 线程安全的可变字符学序列 速度快 StringBuffer 线程不安全的可变字符序列 创建StringBuilder对象 new StringBuilder&…