iOS 直播特殊礼物特效实现方案(Swift实现,超详细!)

news2025/5/25 23:22:26

特殊礼物特效是提升直播互动体验的关键功能,下面我将详细介绍如何在iOS应用中实现各种高级礼物特效。

  1. 基础特效类型

1.1 全屏动画特效

class FullScreenAnimationView: UIView {
    static func show(with gift: GiftModel, in view: UIView) {
        let effectView = FullScreenAnimationView(gift: gift)
        effectView.frame = view.bounds
        view.addSubview(effectView)
        effectView.startAnimation()
    }
    
    private let gift: GiftModel 
    private var imageView: UIImageView!
    private var animationFrames: [UIImage] = []
    
    init(gift: GiftModel) {
        self.gift = gift
        super.init(frame: .zero)
        setupUI()
        loadAnimationFrames()
    }
    
    private func setupUI() {
        backgroundColor = UIColor.black.withAlphaComponent(0.7)
        
        imageView = UIImageView()
        imageView.contentMode = .scaleAspectFit 
        imageView.frame = bounds
        addSubview(imageView)
    }
    
    private func loadAnimationFrames() {
        // 从本地或网络加载动画帧
        for i in 1...30 { // 假设有30帧动画 
            if let image = UIImage(named: "\(gift.id)_frame_\(i)") {
                animationFrames.append(image)
            }
        }
    }
    
    func startAnimation() {
        imageView.animationImages = animationFrames
        imageView.animationDuration = 3.0 
        imageView.animationRepeatCount = 1 
        imageView.startAnimating()
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
            self.removeFromSuperview()
        }
    }
}

1.2 粒子特效

class ParticleEffectView: UIView {
    static func show(with gift: GiftModel, in view: UIView) {
        let effectView = ParticleEffectView(gift: gift)
        effectView.frame = view.bounds 
        view.addSubview(effectView)
        effectView.startEmitter()
    }
    
    private let gift: GiftModel
    private var emitterLayer: CAEmitterLayer!
    
    init(gift: GiftModel) {
        self.gift = gift 
        super.init(frame: .zero)
        setupEmitter()
    }
    
    private func setupEmitter() {
        emitterLayer = CAEmitterLayer()
        emitterLayer.emitterPosition = CGPoint(x: bounds.midX, y: bounds.midY)
        emitterLayer.emitterSize = CGSize(width: bounds.width, height: 1)
        emitterLayer.emitterShape = .sphere 
        emitterLayer.renderMode = .additive 
        emitterLayer.beginTime = CACurrentMediaTime()
        
        let cell = CAEmitterCell()
        cell.contents = UIImage(named: "particle_\(gift.id)")?.cgImage
        cell.birthRate = 50 
        cell.lifetime = 5 
        cell.lifetimeRange = 1 
        cell.velocity = 100
        cell.velocityRange = 50 
        cell.emissionRange = .pi * 2 
        cell.spin = 1 
        cell.spinRange = 2
        cell.scale = 0.5
        cell.scaleRange = 0.3
        cell.scaleSpeed = -0.05 
        cell.alphaSpeed = -0.2 
        
        emitterLayer.emitterCells = [cell]
        layer.addSublayer(emitterLayer)
    }
    
    func startEmitter() {
        DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
            self.emitterLayer.birthRate = 0
            
            DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
                self.removeFromSuperview()
            }
        }
    }
}
  1. 高级特效实现

2.1 3D模型特效 (使用SceneKit)

import SceneKit 
 
class Model3DEffectView: UIView {
    static func show(with gift: GiftModel, in view: UIView) {
        let effectView = Model3DEffectView(gift: gift)
        effectView.frame = view.bounds 
        view.addSubview(effectView)
        effectView.startAnimation()
    }
    
    private let sceneView = SCNView()
    private let gift: GiftModel
    
    init(gift: GiftModel) {
        self.gift = gift
        super.init(frame: .zero)
        setupScene()
    }
    
    private func setupScene() {
        sceneView.frame = bounds
        sceneView.backgroundColor = .clear
        addSubview(sceneView)
        
        let scene = SCNScene()
        sceneView.scene = scene
        
        // 加载3D模型
        if let modelNode = loadModelNode() {
            scene.rootNode.addChildNode(modelNode)
            
            // 添加相机
            let cameraNode = SCNNode()
            cameraNode.camera = SCNCamera()
            cameraNode.position = SCNVector3(x: 0, y: 0, z: 15)
            scene.rootNode.addChildNode(cameraNode)
            
            // 添加光源 
            let lightNode = SCNNode()
            lightNode.light = SCNLight()
            lightNode.light?.type = .omni
            lightNode.position = SCNVector3(x: 0, y: 10, z: 10)
            scene.rootNode.addChildNode(lightNode)
        }
    }
    
    private func loadModelNode() -> SCNNode? {
        guard let sceneURL = Bundle.main.url(forResource: gift.id, withExtension: "scn"),
              let sceneSource = SCNSceneSource(url: sceneURL, options: nil) else {
            return nil
        }
        
        return sceneSource.entryWithIdentifier("MDL_OBJ_ROOT", withClass: SCNNode.self)
    }
    
    func startAnimation() {
        // 旋转动画 
        let rotateAction = SCNAction.rotateBy(x: 0, y: .pi * 2, z: 0, duration: 5)
        sceneView.scene?.rootNode.childNodes.first?.runAction(rotateAction)
        
        // 缩放动画
        let scaleUp = SCNAction.scale(to: 1.5, duration: 1)
        let scaleDown = SCNAction.scale(to: 0.5, duration: 1)
        let scaleSequence = SCNAction.sequence([scaleUp, scaleDown])
        let repeatScale = SCNAction.repeat(scaleSequence, count: 2)
        sceneView.scene?.rootNode.childNodes.first?.runAction(repeatScale)
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
            self.removeFromSuperview()
        }
    }
}

2.2 视频特效 (使用AVPlayer)

class VideoEffectView: UIView {
    static func show(with gift: GiftModel, in view: UIView) {
        let effectView = VideoEffectView(gift: gift)
        effectView.frame = view.bounds 
        view.addSubview(effectView)
        effectView.playVideo()
    }
    
    private let playerLayer = AVPlayerLayer()
    private let gift: GiftModel 
    
    init(gift: GiftModel) {
        self.gift = gift 
        super.init(frame: .zero)
        setupPlayer()
    }
    
    private func setupPlayer() {
        guard let videoURL = URL(string: gift.effectVideoURL) else { return }
        
        let player = AVPlayer(url: videoURL)
        playerLayer.player = player 
        playerLayer.frame = bounds 
        playerLayer.videoGravity = .resizeAspectFill
        layer.addSublayer(playerLayer)
        
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(playerDidFinishPlaying),
            name: .AVPlayerItemDidPlayToEndTime,
            object: player.currentItem
        )
    }
    
    func playVideo() {
        playerLayer.player?.play()
    }
    
    @objc private func playerDidFinishPlaying() {
        removeFromSuperview()
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
}
  1. 复合特效组合

3.1 组合多个特效

class CompositeEffectCoordinator {
    static func playEffect(for gift: GiftModel, in view: UIView) {
        // 根据礼物类型播放不同组合特效
        switch gift.effectLevel {
        case .basic:
            FullScreenAnimationView.show(with: gift, in: view)
            
        case .advanced:
            FullScreenAnimationView.show(with: gift, in: view)
            DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                ParticleEffectView.show(with: gift, in: view)
            }
            
        case .premium:
            FullScreenAnimationView.show(with: gift, in: view)
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                Model3DEffectView.show(with: gift, in: view)
            }
            DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
                VideoEffectView.show(with: gift, in: view)
            }
        }
    }
}

3.2 特效序列管理器

class EffectSequenceManager {
    private var effectQueue: [() -> Void] = []
    private var isPlaying = false 
    
    func addEffect(_ effect: @escaping () -> Void) {
        effectQueue.append(effect)
        playNextIfNeeded()
    }
    
    private func playNextIfNeeded() {
        guard !isPlaying, !effectQueue.isEmpty else { return }
        
        isPlaying = true
        let effect = effectQueue.removeFirst()
        
        effect()
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
            self.isPlaying = false 
            self.playNextIfNeeded()
        }
    }
}
 
// 使用示例 
let effectManager = EffectSequenceManager()
effectManager.addEffect {
    FullScreenAnimationView.show(with: gift1, in: view)
}
effectManager.addEffect {
    ParticleEffectView.show(with: gift2, in: view)
}
  1. 高级交互特效

4.1 用户交互式特效

class InteractiveEffectView: UIView {
    private var touchPoints: [CGPoint] = []
    private var displayLink: CADisplayLink?
    private var particleLayers: [CALayer] = []
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)
        guard let touch = touches.first else { return }
        
        let point = touch.location(in: self)
        createParticleEmitter(at: point)
    }
    
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesMoved(touches, with: event)
        guard let touch = touches.first else { return }
        
        let point = touch.location(in: self)
        touchPoints.append(point)
        
        if touchPoints.count > 5 {
            touchPoints.removeFirst()
        }
        
        if touchPoints.count % 2 == 0 {
            createParticleEmitter(at: point)
        }
    }
    
    private func createParticleEmitter(at position: CGPoint) {
        let emitterLayer = CAEmitterLayer()
        emitterLayer.emitterPosition = position 
        emitterLayer.emitterSize = CGSize(width: 20, height: 20)
        emitterLayer.emitterShape = .circle
        emitterLayer.renderMode = .additive
        
        let cell = CAEmitterCell()
        cell.contents = UIImage(named: "sparkle")?.cgImage 
        cell.birthRate = 20 
        cell.lifetime = 2 
        cell.velocity = 50 
        cell.velocityRange = 30 
        cell.emissionRange = .pi * 2 
        cell.scale = 0.2 
        cell.scaleRange = 0.1
        cell.alphaSpeed = -0.5
        
        emitterLayer.emitterCells = [cell]
        layer.addSublayer(emitterLayer)
        particleLayers.append(emitterLayer)
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
            emitterLayer.birthRate = 0
            DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                emitterLayer.removeFromSuperlayer()
                if let index = self.particleLayers.firstIndex(of: emitterLayer) {
                    self.particleLayers.remove(at: index)
                }
            }
        }
    }
}

4.2 手势控制特效

class GestureControlledEffectView: UIView {
    private var panRecognizer: UIPanGestureRecognizer!
    private var pinchRecognizer: UIPinchGestureRecognizer!
    private var rotationRecognizer: UIRotationGestureRecognizer!
    private var effectNode: SKSpriteNode!
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupScene()
        setupGestures()
    }
    
    private func setupScene() {
        let skView = SKView(frame: bounds)
        skView.backgroundColor = .clear
        addSubview(skView)
        
        let scene = SKScene(size: bounds.size)
        scene.backgroundColor = .clear
        skView.presentScene(scene)
        
        effectNode = SKSpriteNode(imageNamed: "magic_effect")
        effectNode.position = CGPoint(x: scene.size.width/2, y: scene.size.height/2)
        effectNode.setScale(0.5)
        scene.addChild(effectNode)
    }
    
    private func setupGestures() {
        panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)))
        addGestureRecognizer(panRecognizer)
        
        pinchRecognizer = UIPinchGestureRecognizer(target: self, action: #selector(handlePinch(_:)))
        addGestureRecognizer(pinchRecognizer)
        
        rotationRecognizer = UIRotationGestureRecognizer(target: self, action: #selector(handleRotation(_:)))
        addGestureRecognizer(rotationRecognizer)
        
        // 允许多个手势同时识别
        panRecognizer.delegate = self 
        pinchRecognizer.delegate = self
        rotationRecognizer.delegate = self 
    }
    
    @objc private func handlePan(_ recognizer: UIPanGestureRecognizer) {
        let translation = recognizer.translation(in: self)
        effectNode.position.x += translation.x 
        effectNode.position.y -= translation.y
        recognizer.setTranslation(.zero, in: self)
    }
    
    @objc private func handlePinch(_ recognizer: UIPinchGestureRecognizer) {
        effectNode.setScale(effectNode.xScale * recognizer.scale)
        recognizer.scale = 1.0 
    }
    
    @objc private func handleRotation(_ recognizer: UIRotationGestureRecognizer) {
        effectNode.zRotation += recognizer.rotation 
        recognizer.rotation = 0.0
    }
}
 
extension GestureControlledEffectView: UIGestureRecognizerDelegate {
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, 
                          shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
}
  1. 性能优化方案

5.1 对象池模式

class EffectPool {
    static let shared = EffectPool()
    
    private var fullScreenEffects: [FullScreenAnimationView] = []
    private var particleEffects: [ParticleEffectView] = []
    
    func dequeueFullScreenEffect(for gift: GiftModel) -> FullScreenAnimationView {
        if let effect = fullScreenEffects.first(where: { $0.isHidden }) {
            effect.gift = gift
            effect.isHidden = false 
            return effect 
        } else {
            let effect = FullScreenAnimationView(gift: gift)
            fullScreenEffects.append(effect)
            return effect
        }
    }
    
    func dequeueParticleEffect(for gift: GiftModel) -> ParticleEffectView {
        if let effect = particleEffects.first(where: { $0.isHidden }) {
            effect.gift = gift
            effect.isHidden = false 
            return effect 
        } else {
            let effect = ParticleEffectView(gift: gift)
            particleEffects.append(effect)
            return effect
        }
    }
    
    func recycle(effect: UIView) {
        effect.isHidden = true 
        effect.layer.removeAllAnimations()
    }
}

5.2 特效资源预加载

class EffectPreloader {
    static func preloadEffects(for gifts: [GiftModel]) {
        DispatchQueue.global(qos: .userInitiated).async {
            for gift in gifts {
                switch gift.effectType {
                case .animation:
                    _ = UIImage(contentsOfFile: Bundle.main.path(forResource: "\(gift.id)_frame_1", ofType: "png") ?? "")
                    
                case .particle:
                    _ = UIImage(contentsOfFile: Bundle.main.path(forResource: "particle_\(gift.id)", ofType: "png") ?? "")
                    
                case .video:
                    let _ = AVAsset(url: URL(string: gift.effectVideoURL)!)
                    
                case .model3D:
                    _ = SCNScene(named: "\(gift.id).scn")
                }
            }
        }
    }
}
  1. 特效配置文件
{
  "effects": [
    {
      "id": "rocket",
      "name": "超级火箭",
      "type": "composite",
      "components": [
        {
          "type": "animation",
          "duration": 2.0,
          "frames": 30,
          "framePrefix": "rocket_anim_"
        },
        {
          "type": "particle",
          "particleImage": "rocket_particle",
          "birthRate": 200,
          "lifetime": 3.0,
          "velocity": 150
        },
        {
          "type": "sound",
          "file": "rocket_launch.mp3",
          "volume": 1.0 
        }
      ],
      "trigger": "immediate",
      "zOrder": 1000 
    },
    {
      "id": "fireworks",
      "name": "豪华烟花",
      "type": "sequence",
      "components": [
        {
          "type": "animation",
          "duration": 1.5,
          "frames": 45,
          "framePrefix": "fireworks_launch_"
        },
        {
          "type": "particle",
          "particleImage": "sparkle",
          "birthRate": 500,
          "lifetime": 2.5,
          "velocity": 80,
          "delay": 1.5 
        }
      ],
      "trigger": "delayed",
      "zOrder": 900
    }
  ]
}

实现建议

  1. 分层架构设计:

    • 表现层:处理特效的视觉展示
    • 控制层:管理特效的播放顺序和组合
    • 数据层:加载和解析特效配置
  2. 性能监控:

    func monitorPerformance() {
        DispatchQueue.main.async {
            let fps = CADisplayLink(target: self, selector: #selector(checkFPS))
            fps.add(to: .current, forMode: .common)
        }
    }
    
    @objc private func checkFPS(displayLink: CADisplayLink) {
        if displayLink.timestamp - lastTimestamp >= 1 {
            let fps = Double(frameCount) / (displayLink.timestamp - lastTimestamp)
            print("Current FPS: \(fps)")
            
            if fps < 50 {
                // 降低特效质量或数量
                EffectQualityManager.shared.reduceQuality()
            }
            
            lastTimestamp = displayLink.timestamp 
            frameCount = 0
        }
        frameCount += 1 
    }
    
  3. 动态调整:

    • 根据设备性能自动调整特效质量
    • 在低电量模式下减少粒子数量
    • 后台时暂停复杂特效

通过以上方案,可以实现从简单到复杂的各种特殊礼物特效,并根据实际需求灵活扩展。记得在实现过程中充分考虑性能优化和内存管理,确保特效的流畅运行。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

9. 现代循环神经网络

文章目录 9.1. 门控循环单元&#xff08;GRU&#xff09;9.1.1. 门控隐状态9.1.1.1. 重置门和更新门9.1.1.2. 候选隐状态9.1.1.3. 隐状态 9.1.2. 从零开始实现9.1.2.1. 初始化模型参数9.1.2.2. 定义模型 9.1.3. 简洁实现9.1.4. 小结 9.2. 长短期记忆网络&#xff08;LSTM&#…

视频太大?用魔影工厂压缩并转MP4,画质不打折!

在日常生活中&#xff0c;我们常常需要将视频文件转换成不同的格式以适应各种设备或平台的播放需求。魔影工厂作为一款功能强大且操作简单的视频转换工具&#xff0c;深受用户喜爱。本文中简鹿办公将手把手教你如何使用魔影工厂将视频转换为MP4格式&#xff0c;并进行个性化设置…

最宽温度范围文本格式PT1000分度表-200~850度及PT1000铂电阻温度传感器计算公式

常用PT铂电阻温度传感器 该图片来自网络&#xff0c;在此对图片作者表示感谢。 白色陶瓷面为测温面。 近距离图片。 常用的有PT100、PT500、PT1000&#xff0c;不常用的还有 PT50、PT200、PT10000等&#xff0c;PT代表铂电阻&#xff0c;后面的数字是零摄氏度时电阻值&#…

机器学习算法-sklearn源起

scikit-learn&#xff08;简称 sklearn&#xff09;是 Python 中最流行的开源机器学习库之一&#xff0c;基于 NumPy、SciPy 和 Matplotlib 构建。它提供了丰富的机器学习算法和工具&#xff0c;适用于数据挖掘和数据分析任务。以下是其核心特点的简介&#xff1a; 1、sklearn主…

注册并创建一个微信小程序

目录 &#xff08;一&#xff09;前往微信公众平台&#xff0c;并注册一个微信小程序账号 &#xff08;二&#xff09;配置微信小程序 &#xff08;三&#xff09;创建微信小程序项目 1.流程 1.1获取小程序ID 1.2下载微信开发者工具 1.3安装微信开发者工具 2.创建项目…

计算机网络——每一层的用到的设备及其作用

计算机网络基础 OSI参考模型TCP/IP协议族集线器&#xff08;Hub&#xff09;交换机&#xff08;Switch&#xff09;路由器&#xff08;Router&#xff09;功能特点无线路由器&#xff08;家庭宽带&#xff09;光猫功能 网关&#xff08;Gateway&#xff09;功能应用场景特点 IP…

【Web前端】JavaScript入门与基础(一)

JavaScript简介 JavaScript 是一种轻量级的脚本语言。所谓“脚本语言”&#xff0c;指的是它不具备开发操作系统的能力&#xff0c;而是只用来编写控制其他大型应用程序的“脚本”。 JavaScript 是一种嵌入式&#xff08;embedded&#xff09;语言。它本身提供的核心语法不算…

前端大文件上传性能优化实战:分片上传分析与实战

前端文件分片是大文件上传场景中的重要优化手段&#xff0c;其必要性和优势主要体现在以下几个方面&#xff1a; 一、必要性分析 1. 突破浏览器/服务器限制 浏览器限制&#xff1a;部分浏览器对单次上传文件大小有限制&#xff08;如早期IE限制4GB&#xff09; 服务器限制&a…

Linux服务器配置深度学习环境(Pytorch+Anaconda极简版)

前言&#xff1a; 最近做横向需要使用实验室服务器跑模型&#xff0c;之前用师兄的账号登录服务器跑yolo&#xff0c;3张3090一轮14秒&#xff0c;我本地一张4080laptop要40秒&#xff0c;效率还是快很多&#xff0c;&#xff08;这么算一张4080桌面版居然算力能比肩3090&#…

超低延迟音视频直播技术的未来发展与创新

引言 音视频直播技术正在深刻改变着我们的生活和工作方式&#xff0c;尤其是在教育、医疗、安防、娱乐等行业。无论是全球性的体育赛事、远程医疗、在线教育&#xff0c;还是智慧安防、智能家居等应用场景&#xff0c;都离不开音视频技术的支持。为了应对越来越高的需求&#x…

Java 内存模型(JMM)深度解析:理解多线程内存可见性问题

Java 内存模型&#xff08;JMM&#xff09;深度解析&#xff1a;理解多线程内存可见性问题 在 Java 编程中&#xff0c;多线程的运用能够显著提升程序的执行效率&#xff0c;但与此同时&#xff0c;多线程环境下的一些问题也逐渐凸显。其中&#xff0c;内存可见性问题是一个关…

转移dp简单数学数论

1.转移dp问题 昨天的练习赛上有一个很好玩的起终点问题&#xff0c;第一时间给出bfs的写法。 但是写到后面发现不行&#xff0c;还得是的dp转移的写法才能完美的解决这道题目。 每个格子可以经过可以不经过&#xff0c;因此它的状态空间是2^&#xff08;n*m&#xff09;&…

动静态库--

目录 一 静态库 1. 创建静态库 2. 使用静态库 2.1 第一种 2.2 第二种 二 动态库 1. 创建动态库 2. 使用动态库 三 静态库 VS 动态库 四 动态库加载 1. 可执行文件加载 2. 动态库加载 一 静态库 Linux静态库&#xff1a;.a结尾 Windows静态库&#xff1a;.lib结尾…

git clone时出现无法访问的问题

git clone时出现无法访问的问题 问题&#xff1a; 由于我的git之前设置了代理&#xff0c;然后在这次克隆时又没有打开代理 解决方案&#xff1a; 1、如果不需要代理&#xff0c;直接取消 Git 的代理设置&#xff1a; git config --global --unset http.proxy git config --gl…

文件系统·linux

目录 磁盘简介 Ext文件系统 块 分区 分组 inode 再谈inode 路径解析 路径缓存 再再看inode 挂载 小知识 磁盘简介 磁盘&#xff1a;一个机械设备&#xff0c;用于储存数据。 未被打开的文件都是存在磁盘上的&#xff0c;被打开的加载到内存中。 扇区&#xff1a;是…

【Matlab】雷达图/蛛网图

文章目录 一、简介二、安装三、示例四、所有参数说明 一、简介 雷达图&#xff08;Radar Chart&#xff09;又称蛛网图&#xff08;Spider Chart&#xff09;是一种常见的多维数据可视化手段&#xff0c;能够直观地对比多个指标并揭示其整体分布特征。 雷达图以中心点为原点&…

使用JProfiler进行Java应用性能分析

文章目录 一、基本概念 二、Windows系统中JProfiler的安装 1、下载exe文件 2、安装JProfiler 三、JProfiler的破解 四、IDEA中配置JProfiler 1、安装JProfiler插件 2、关联本地磁盘中JProfiler软件的执行文件 3、IDEA中启动JProfiler 五、监控本地主机中的Java应用 …

遥感解译项目Land-Cover-Semantic-Segmentation-PyTorch之一推理模型

文章目录 效果项目下载项目安装安装步骤1、安装环境2、新建虚拟环境和安装依赖测试模型效果效果 项目下载 项目地址 https://github.com/souvikmajumder26/Land-Cover-Semantic-Segmentation-PyTorch 可以直接通过git下载 git clone https://github.com/souvikmajumder26/Lan…

六、【前端启航篇】Vue3 项目初始化与基础布局:搭建美观易用的管理界面骨架

【前端启航篇】Vue3 项目初始化与基础布局&#xff1a;搭建美观易用的管理界面骨架 前言技术选型回顾与准备准备工作第一步&#xff1a;进入前端项目并安装 Element Plus第二步&#xff1a;在 Vue3 项目中引入并配置 Element Plus第三步&#xff1a;设计基础页面布局组件第四步…

C++ 前缀和数组

一. 一维数组前缀和 1.1. 定义 前缀和算法通过预处理数组&#xff0c;计算从起始位置到每个位置的和&#xff0c;生成一个新的数组&#xff08;前缀和数组&#xff09;。利用该数组&#xff0c;可以快速计算任意区间的和&#xff0c;快速求出数组中某一段连续区间的和。 1.2. …