当前位置: 首页 > news >正文

跨平台WPF音乐商店应用程序

目录

一 简介

二 设计思路

三 源码


一 简介

支持在线检索音乐,支持实时浏览当前收藏的音乐及音乐数据的持久化。

二 设计思路

采用MVVM架构,前后端分离,子界面弹出始终位于主界面的中心。

三 源码

视窗引导启动源码:

namespace Avalonia.MusicStore
{public class ViewLocator : IDataTemplate{public Control? Build(object? data){if (data is null)return null;var name = data.GetType().FullName!.Replace("ViewModel", "View", StringComparison.Ordinal);var type = Type.GetType(name);if (type != null){var control = (Control)Activator.CreateInstance(type)!;control.DataContext = data;return control;}return new TextBlock { Text = "Not Found: " + name };}public bool Match(object? data){return data is ViewModelBase;}}
}using Avalonia;
using Avalonia.ReactiveUI;
using System;namespace Avalonia.MusicStore
{internal sealed class Program{// Initialization code. Don't use any Avalonia, third-party APIs or any// SynchronizationContext-reliant code before AppMain is called: things aren't initialized// yet and stuff might break.[STAThread]public static void Main(string[] args) => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);// Avalonia configuration, don't remove; also used by visual designer.public static AppBuilder BuildAvaloniaApp()=> AppBuilder.Configure<App>().UsePlatformDetect().WithInterFont().LogToTrace().UseReactiveUI();}
}

模型源码:

using iTunesSearch.Library;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;namespace Avalonia.MusicStore.Models
{public class Album{private static iTunesSearchManager s_SearchManager = new();public string Artist { get; set; }public string Title { get; set; }public string CoverUrl { get; set; }public Album(string artist, string title, string coverUrl){Artist = artist;Title = title;CoverUrl = coverUrl;}public static async Task<IEnumerable<Album>> SearchAsync(string searchTerm){var query = await s_SearchManager.GetAlbumsAsync(searchTerm).ConfigureAwait(false);return query.Albums.Select(x =>new Album(x.ArtistName, x.CollectionName,x.ArtworkUrl100.Replace("100x100bb", "600x600bb")));}private static HttpClient s_httpClient = new();private string CachePath => $"./Cache/{Artist} - {Title}";public async Task<Stream> LoadCoverBitmapAsync(){if (File.Exists(CachePath + ".bmp")){return File.OpenRead(CachePath + ".bmp");}else{var data = await s_httpClient.GetByteArrayAsync(CoverUrl);return new MemoryStream(data);}}public async Task SaveAsync(){if (!Directory.Exists("./Cache")){Directory.CreateDirectory("./Cache");}using (var fs = File.OpenWrite(CachePath)){await SaveToStreamAsync(this, fs);}}public Stream SaveCoverBitmapStream(){return File.OpenWrite(CachePath + ".bmp");}private static async Task SaveToStreamAsync(Album data, Stream stream){await JsonSerializer.SerializeAsync(stream, data).ConfigureAwait(false);}public static async Task<Album> LoadFromStream(Stream stream){return (await JsonSerializer.DeserializeAsync<Album>(stream).ConfigureAwait(false))!;}public static async Task<IEnumerable<Album>> LoadCachedAsync(){if (!Directory.Exists("./Cache")){Directory.CreateDirectory("./Cache");}var results = new List<Album>();foreach (var file in Directory.EnumerateFiles("./Cache")){if (!string.IsNullOrWhiteSpace(new DirectoryInfo(file).Extension)) continue;await using var fs = File.OpenRead(file);results.Add(await Album.LoadFromStream(fs).ConfigureAwait(false));}return results;}}
}

模型视图源码:

using Avalonia.Media.Imaging;
using Avalonia.MusicStore.Models;
using ReactiveUI;
using System.Threading.Tasks;namespace Avalonia.MusicStore.ViewModels
{public class AlbumViewModel : ViewModelBase{private readonly Album _album;public AlbumViewModel(Album album){_album = album;}public string Artist => _album.Artist;public string Title => _album.Title;private Bitmap? _cover;public Bitmap? Cover{get => _cover;private set => this.RaiseAndSetIfChanged(ref _cover, value);}public async Task LoadCover(){await using (var imageStream = await _album.LoadCoverBitmapAsync()){Cover = await Task.Run(() => Bitmap.DecodeToWidth(imageStream, 400));}}public async Task SaveToDiskAsync(){await _album.SaveAsync();if (Cover != null){var bitmap = Cover;await Task.Run(() =>{using (var fs = _album.SaveCoverBitmapStream()){bitmap.Save(fs);}});}}}
}
using Avalonia.MusicStore.Models;
using ReactiveUI;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Windows.Input;namespace Avalonia.MusicStore.ViewModels
{public class MainWindowViewModel : ViewModelBase{public ICommand BuyMusicCommand { get; }public Interaction<MusicStoreViewModel, AlbumViewModel?> ShowDialog { get; }public ObservableCollection<AlbumViewModel> Albums { get; } = new();public MainWindowViewModel(){ShowDialog = new Interaction<MusicStoreViewModel, AlbumViewModel?>();BuyMusicCommand = ReactiveCommand.CreateFromTask(async () =>{var store = new MusicStoreViewModel();var result = await ShowDialog.Handle(store);if (result != null){Albums.Add(result);await result.SaveToDiskAsync();}});RxApp.MainThreadScheduler.Schedule(LoadAlbums);}private async void LoadAlbums(){var albums = (await Album.LoadCachedAsync()).Select(x => new AlbumViewModel(x));foreach (var album in albums){Albums.Add(album);}foreach (var album in Albums.ToList()){await album.LoadCover();}}}
}
using Avalonia.MusicStore.Models;
using ReactiveUI;
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive;
using System.Reactive.Linq;
using System.Threading;namespace Avalonia.MusicStore.ViewModels
{public class MusicStoreViewModel : ViewModelBase{private string? _searchText;private bool _isBusy;public string? SearchText{get => _searchText;set => this.RaiseAndSetIfChanged(ref _searchText, value);}public bool IsBusy{get => _isBusy;set => this.RaiseAndSetIfChanged(ref _isBusy, value);}private AlbumViewModel? _selectedAlbum;public ObservableCollection<AlbumViewModel> SearchResults { get; } = new();public AlbumViewModel? SelectedAlbum{get => _selectedAlbum;set => this.RaiseAndSetIfChanged(ref _selectedAlbum, value);}public MusicStoreViewModel(){this.WhenAnyValue(x => x.SearchText).Throttle(TimeSpan.FromMilliseconds(400)).ObserveOn(RxApp.MainThreadScheduler).Subscribe(DoSearch!);BuyMusicCommand = ReactiveCommand.Create(() =>{return SelectedAlbum;});}private async void DoSearch(string s){IsBusy = true;SearchResults.Clear();_cancellationTokenSource?.Cancel();_cancellationTokenSource = new CancellationTokenSource();var cancellationToken = _cancellationTokenSource.Token;if (!string.IsNullOrWhiteSpace(s)){var albums = await Album.SearchAsync(s);foreach (var album in albums){var vm = new AlbumViewModel(album);SearchResults.Add(vm);}if (!cancellationToken.IsCancellationRequested){LoadCovers(cancellationToken);}}IsBusy = false;}private async void LoadCovers(CancellationToken cancellationToken){foreach (var album in SearchResults.ToList()){await album.LoadCover();if (cancellationToken.IsCancellationRequested){return;}}}private CancellationTokenSource? _cancellationTokenSource;public ReactiveCommand<Unit, AlbumViewModel?> BuyMusicCommand { get; }}
}
using ReactiveUI;namespace Avalonia.MusicStore.ViewModels
{public class ViewModelBase : ReactiveObject{}
}

视图源码:

<UserControlx:Class="Avalonia.MusicStore.Views.AlbumView"xmlns="https://github.com/avaloniaui"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:vm="using:Avalonia.MusicStore.ViewModels"Width="200"d:DesignHeight="450"d:DesignWidth="800"x:DataType="vm:AlbumViewModel"mc:Ignorable="d"><StackPanel Width="200" Spacing="5"><Border ClipToBounds="True" CornerRadius="10"><Panel Background="#7FFF22DD"><ImageWidth="200"Source="{Binding Cover}"Stretch="Uniform" /><Panel Height="200" IsVisible="{Binding Cover, Converter={x:Static ObjectConverters.IsNull}}"><PathIconWidth="75"Height="75"Data="{StaticResource music_regular}" /></Panel></Panel></Border><TextBlock HorizontalAlignment="Center" Text="{Binding Title}" /><TextBlock HorizontalAlignment="Center" Text="{Binding Artist}" /></StackPanel>
</UserControl>
<Windowx:Class="Avalonia.MusicStore.Views.MainWindow"xmlns="https://github.com/avaloniaui"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:views="clr-namespace:Avalonia.MusicStore.Views"xmlns:vm="using:Avalonia.MusicStore.ViewModels"Title="Avalonia.MusicStore"d:DesignHeight="450"d:DesignWidth="800"x:DataType="vm:MainWindowViewModel"Background="Transparent"ExtendClientAreaToDecorationsHint="True"Icon="/Assets/avalonia-logo.ico"TransparencyLevelHint="AcrylicBlur"WindowStartupLocation="CenterScreen"mc:Ignorable="d"><Panel><ExperimentalAcrylicBorder IsHitTestVisible="False"><ExperimentalAcrylicBorder.Material><ExperimentalAcrylicMaterialBackgroundSource="Digger"MaterialOpacity="0.65"TintColor="Black"TintOpacity="1" /></ExperimentalAcrylicBorder.Material></ExperimentalAcrylicBorder><Panel Margin="40"><ButtonHorizontalAlignment="Right"VerticalAlignment="Top"Command="{Binding BuyMusicCommand}"><PathIcon Data="{StaticResource store_microsoft_regular}" /></Button><ItemsControl Margin="0,40,0,0" ItemsSource="{Binding Albums}"><ItemsControl.ItemsPanel><ItemsPanelTemplate><WrapPanel /></ItemsPanelTemplate></ItemsControl.ItemsPanel><ItemsControl.ItemTemplate><DataTemplate><views:AlbumView Margin="0,0,20,20" /></DataTemplate></ItemsControl.ItemTemplate></ItemsControl></Panel></Panel></Window>
using Avalonia.MusicStore.ViewModels;
using Avalonia.ReactiveUI;
using ReactiveUI;
using System.Threading.Tasks;namespace Avalonia.MusicStore.Views
{public partial class MainWindow : ReactiveWindow<MainWindowViewModel>{public MainWindow(){InitializeComponent();this.WhenActivated(action => action(ViewModel!.ShowDialog.RegisterHandler(DoShowDialogAsync)));}private async Task DoShowDialogAsync(InteractionContext<MusicStoreViewModel,AlbumViewModel?> interaction){var dialog = new MusicStoreWindow();dialog.DataContext = interaction.Input;var result = await dialog.ShowDialog<AlbumViewModel?>(this);interaction.SetOutput(result);}}
}
<UserControlx:Class="Avalonia.MusicStore.Views.MusicStoreView"xmlns="https://github.com/avaloniaui"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:vm="using:Avalonia.MusicStore.ViewModels"d:DesignHeight="450"d:DesignWidth="800"x:DataType="vm:MusicStoreViewModel"mc:Ignorable="d"><DockPanel><StackPanel DockPanel.Dock="Top"><TextBox Text="{Binding SearchText}" Watermark="Search for Albums...." /><ProgressBar IsIndeterminate="True" IsVisible="{Binding IsBusy}" /></StackPanel><ButtonHorizontalAlignment="Center"Command="{Binding BuyMusicCommand}"Content="Buy Album"DockPanel.Dock="Bottom" /><ListBoxMargin="0,20"Background="Transparent"ItemsSource="{Binding SearchResults}"SelectedItem="{Binding SelectedAlbum}"><ListBox.ItemsPanel><ItemsPanelTemplate><WrapPanel /></ItemsPanelTemplate></ListBox.ItemsPanel></ListBox></DockPanel>
</UserControl>
<Windowx:Class="Avalonia.MusicStore.Views.MusicStoreWindow"xmlns="https://github.com/avaloniaui"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:views="using:Avalonia.MusicStore.Views"Title="MusicStoreWindow"Width="1000"Height="550"ExtendClientAreaToDecorationsHint="True"TransparencyLevelHint="AcrylicBlur"WindowStartupLocation="CenterOwner"mc:Ignorable="d"><Panel><ExperimentalAcrylicBorder IsHitTestVisible="False"><ExperimentalAcrylicBorder.Material><ExperimentalAcrylicMaterialBackgroundSource="Digger"MaterialOpacity="0.65"TintColor="Black"TintOpacity="1" /></ExperimentalAcrylicBorder.Material></ExperimentalAcrylicBorder><Panel Margin="40"><views:MusicStoreView /></Panel></Panel>
</Window>
using Avalonia.MusicStore.ViewModels;
using Avalonia.ReactiveUI;
using ReactiveUI;
using System;namespace Avalonia.MusicStore.Views
{public partial class MusicStoreWindow : ReactiveWindow<MusicStoreViewModel>{public MusicStoreWindow(){InitializeComponent();this.WhenActivated(action => action(ViewModel!.BuyMusicCommand.Subscribe(Close)));}}
}

相关文章:

跨平台WPF音乐商店应用程序

目录 一 简介 二 设计思路 三 源码 一 简介 支持在线检索音乐&#xff0c;支持实时浏览当前收藏的音乐及音乐数据的持久化。 二 设计思路 采用MVVM架构&#xff0c;前后端分离&#xff0c;子界面弹出始终位于主界面的中心。 三 源码 视窗引导启动源码&#xff1a; namesp…...

设计模式简述(一)

定义&#xff1a;设计模式指的是在软件开发过程中&#xff0c;经过验证的&#xff0c;用于解决在特定环境下&#xff0c;重复出现的&#xff0c;特定问题的解决方案。创建型设计模式关注对象的创建过程&#xff0c;提供了更灵活、可扩展的对象创建机制。结构型设计模式用于解决…...

OSI参考模型:解析网络通信的七层框架

引言 在现代计算机网络中&#xff0c;OSI&#xff08;开放式系统互联&#xff09;参考模型是理解和设计网络通信协议的基础。1978年由国际标准化组织&#xff08;ISO&#xff09;提出&#xff0c;OSI模型定义了网络通信的七层结构&#xff0c;每一层都承担着特定的功能&#x…...

QT通用配置文件库(QPreferences)

QT通用配置文件库(QPreferences) QPreferences项目是基于nlohmann/json的qt可视化配置文件库&#xff0c;将配置保存成json格式&#xff0c;并提供UI查看与修改&#xff0c;可通过cmake可快速添加进项目。默认支持基本类型、stl常用容器、基本类型与stl容器组成的结构体&#…...

如何搭建一个RADIUS服务器?

1. 系统环境 1.1.操作系统 Ubuntu-20.04.1 &#xff08;kernel: 5.15.0-58-generic&#xff09; 1.2.所需软件 FreeRADIUS MariaDB 1.3.注意事项 本文提到的所有操作&#xff0c;都是以root 身份执行&#xff1b; 2. FreeRADIUS的安装 2.1. 安装FreeRADIUS服务器程序 以…...

双机热备综合实验

1&#xff0c;对现有网络进行改造升级&#xff0c;将当个防火墙组网改成双机热备的组网形式&#xff0c;做负载分担模式&#xff0c;游客区和DMZ区走FW3&#xff0c;生产区和办公区的流量走FW1 2&#xff0c;办公区上网用户限制流量不超过100M&#xff0c;其中销售部人员在其基…...

Java和Python的图结构如何实现图的深度优先搜索算法

Java和Python的图结构如何实现图的深度优先搜索算法&#xff1f; 在Java和Python中&#xff0c;实现深度优先搜索&#xff08;DFS&#xff09;算法的基本思路都是通过递归或栈来探索图的各个节点。 Java实现DFS&#xff1a;Java import java.util.ArrayList; import java.uti…...

Web学习day05

html&css 目录 html&css 文章目录 一、web开发 1.1工作流程 1.2开发技术 二、HTML 2.1HTML规范 2.2基础标签 2.2.1标题 2.2.2水平线 2.2.3段落和换行 2.2.4文字效果 2.2.5超链接 2.2.6图像 2.2.7音频和视频 三、布局标签 3.1列表 3.2容器 3.3表格 3…...

LINUX客户端client(socket、connect)实现客户端发送,服务器接收

SERVICE端见前一篇文章 5. 客户端连接函数 connect()&#xff08;与前面的bind一样&#xff09; int connect (int sockfd, struct sockaddr * serv_addr, int addrlen) 参数&#xff1a; sockfd: 通过 socket() 函数拿到的 fd addr:struct sockaddr 的结构体变量地址 addr…...

【网络安全科普】勒索病毒 防护指南

勒索病毒简介 勒索病毒是一种恶意软件&#xff0c;也称为勒索软件&#xff08;Ransomware&#xff09;&#xff0c;其主要目的是在感染计算机后加密用户文件&#xff0c;并要求用户支付赎金以获取解密密钥。这种类型的恶意软件通常通过电子邮件附件、恶意链接、下载的软件或漏洞…...

TFHE库,fftw和googletest库安装

点个关注吧&#xff01;本文主要关注于TFHE的安装与常见的问题 1.TFHE的git链接&#xff1a; https://github.com/tfhe/tfhe git clone --recurse-submodules --branchmaster https://github.com/tfhe/tfhe.git 2.安装 mkdir build cd build cmake ../src -DENABLE_TESTSon -D…...

关于Spring Boot IOCDC,看这一篇就够了

一&#xff0c;Spring是什么及常用注解 先说什么是spring&#xff0c;在前面的博客中已经知道了&#xff0c;spring是一个开源框架&#xff0c;为了让我们开发更加简单&#xff0c;那关于ioc呢&#xff0c;一句话概况一下&#xff1a;Spring就是包含了众多工具方法的Ioc容器 …...

Model Import Settings

前言 在可视化3D世界中&#xff0c;模型是3D世界的核心&#xff0c;你可以没有贴图&#xff0c;可以没有特效&#xff0c;甚至可以没有用户交互界面&#xff0c;但必须得有模型来描述世界的基本样貌。 在3D世界中&#xff0c;由点线面构成了模型的轮廓&#xff1b;由UV和纹理&a…...

腾讯云COS托管静态网站,以及如何解决访问出现了下载网页的情况

腾讯云对象存储&#xff08;Cloud Object Storage&#xff0c;简称COS&#xff09;&#xff0c;与其他云厂商所提供的云对象存储都是面向非结构化数据&#xff0c;只是每个云厂商的叫法有别于他家&#xff0c;或许是更能彰显厂商的品牌吧&#xff01; 但不管云厂商怎么给云对象…...

软件设计模式: 抽象工厂

抽象工厂 一、解决的问题 抽象工厂模式主要解决了在具有多个产品族的情况下&#xff0c;如何统一管理创建相关产品对象的问题。 当系统需要创建一系列相互关联或相互依赖的对象&#xff0c;并且这些对象可以形成多个不同的产品族时&#xff0c;如果直接由客户端去分别创建这…...

使用Vuepress搭建个人网站

网站地址&#xff1a;bloggo.chat...

lua 写一个 不同时区之间转换日期和时间 函数

这个函数用于调整时间戳以适应不同的时区。它接受五个参数&#xff1a;format、timeStamp、dontFixForTimeOffset、currentServerTimeZone和showLog。返回 os.date&#xff0c;可以转化成指定格式的年月日时间 ### 功能 该函数的主要功能是根据给定的时区偏移量调整时间戳&am…...

谷粒商城——session共享

问题1 一个系统中不同微服务的session共享。 问题1的解决办法 1. session复制的方法&#xff1a;微服务的副本之间通过通信共享session。这样每一个微服务的副本都会保存所有的session。&#xff08;缺点&#xff1a;造成大量的通信&#xff0c;多处额外的通信开销。&#x…...

Java 语言及其常用集合类的操作,以及反射机制与注解

目录 一、Java 语言概述 二、Java 集合框架 ArrayList 操作示例&#xff1a; HashMap 操作示例&#xff1a; 三、反射机制 1. 反射的示例 五、总结 Java 是一种广泛使用的高级编程语言&#xff0c;因其平台独立性、简洁性及丰富的 API 而备受开发者青睐。 一、Java 语言…...

《系统架构设计师教程(第2版)》第12章-信息系统架构设计理论与实践-02-信息系统架构

文章目录 1. 概述1.1 信息系统架构&#xff08;ISA&#xff09;1.2 架构风格 2. 信息系统架构分类2.1 信息系统物理结构2.1.1 集中式结构2.1.2 分布式结构 2.2 信息系统的逻辑结构1&#xff09;横向综合2&#xff09;纵向综合3&#xff09;纵横综合 3. 信息系统架构的一般原理4…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学&#xff08;ECC&#xff09;是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础&#xff0c;例如椭圆曲线数字签…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap&#xff08;位图&#xff09;是Android应用内存占用的“头号杀手”。一张1080P&#xff08;1920x1080&#xff09;的图片以ARGB_8888格式加载时&#xff0c;内存占用高达8MB&#xff08;192010804字节&#xff09;。据统计&#xff0c;超过60%的应用OOM崩溃与Bitm…...