【SkiaSharp绘图09】SKBitmap属性详解

文章目录

  • SKBitmap
    • 与Bitmap性能对比
    • 对比结果
  • 构造函数
    • SKBitmap()
    • SKBitmap(SKImageInfo)
    • SKBitmap(Int32, Int32, SKColorType, SKAlphaType, SKColorSpace)
  • SKBitmap属性
    • AlphaType
    • ByteCount
    • Bytes
    • BytesPerPixel
    • ColorSpace
    • ColorType
    • DrawsNothing
    • Info
    • IsEmpty
    • IsImmutable
    • IsNull
    • Pixels
    • ReadyToDraw
    • RowBytes
    • Width、Height
    • 示例

SKBitmap

  • 光栅位图,整数的宽度、高度,格式(颜色类型)以及指向实际像素的指针。
  • SkBitmap 构建于 SkImageInfo 之上,包含整数宽度和高度、描述像素格式的 SkColorType 和 SkAlphaType 以及描述颜色范围的 SkColorSpace。 SkBitmap指向SkPixelRef,它描述了像素的物理数组。 SkImageInfo 边界可以位于完全位于 SkPixelRef 边界内的任何位置。
  • SkBitmap可以使用SkCanvas来绘制。 SkBitmap 可以是 SkCanvas 绘制成员函数的绘制目标。 SkBitmap 作为像素容器的灵活性限制了目标平台可用的一些优化。
  • 如果像素数组主要是只读的,请使用 SkImage 以获得更好的性能。如果主要写入像素数组,请使用 SkSurface 以获得更好的性能。
  • SkBitmap 不是线程安全的。尽管线程可以共享底层像素数组,但每个线程都必须拥有自己的 SkBitmap 字段副本。
  • 使用GetPixels()获取位图的像素地址。(注意,1.60.0版本之后不再需要调用LockPixels和UnlockPixels方法)。

与Bitmap性能对比

分别测试,单像素GetPixel与指针访问的性能。

  1. 分别加载SKBitmap和Bitmap图像
var canvas = e.Surface.Canvas;
var info = e.Info;
canvas.Clear(SKColors.White);if (skBmp == null)
{skBmp = SKBitmap.Decode(@"Images\AIWoman.png");
}
if (bitmap == null)
{bitmap = new System.Drawing.Bitmap(@"Images\AIWoman.png");
}
  1. 逐像素分别访问SKBitmap与Bitmap对象
#region GetPixel对比
long sumR = 0;
long sumG = 0;
long sumB = 0;var sw = Stopwatch.StartNew();
for (var row = 0; row < skBmp.Height; row++)
{for (var col = 0; col < skBmp.Width; col++){var color = skBmp.GetPixel(col, row);sumR += color.Red;sumG += color.Green;sumB += color.Blue;}
}
sw.Stop();long totalR = 0;
long totalG = 0;
long totalB = 0;var sw1 = Stopwatch.StartNew();for (var row = 0; row < bitmap.Height; row++) 
{for (var col = 0; col < bitmap.Width; col++){var color = bitmap.GetPixel(col, row);totalR += color.R;totalG += color.G;totalB += color.B;}
}
sw1.Stop();
#endregion
  1. 分别显示耗时
var xOffset = 20F;
var yOffset = 50F;
var paint = new SKPaint();
paint.IsAntialias = true;
paint.TextSize = 24;
paint.Typeface = SKTypeface.FromFamilyName("微软雅黑");
canvas.DrawText($"图像大小:{skBmp.Width}x{skBmp.Height}", xOffset, yOffset, paint);
yOffset += paint.FontSpacing;
canvas.DrawText("GetPixel效率对比:", xOffset, yOffset, paint);
yOffset += paint.FontSpacing;
canvas.DrawText($"SKBitmap GetPixel耗时:{sw.ElapsedMilliseconds}ms,R:{sumR},G:{sumG},B:{sumB}", xOffset, yOffset, paint);
yOffset += paint.FontSpacing;
canvas.DrawText($"Bitmap GetPixel耗时:{sw1.ElapsedMilliseconds}ms,R:{totalR},G:{totalG},B:{totalB}", xOffset, yOffset, paint);
yOffset += paint.FontSpacing;
  1. 使用指针方式逐像素访问
#region  指针访问sumR = 0;
sumG = 0;
sumB = 0;sw = Stopwatch.StartNew();
// 获取指向像素数据的指针
IntPtr pixelsPtr = skBmp.GetPixels();
int width = bitmap.Width;
int height = bitmap.Height;
int bytesPerPixel = skBmp.Info.BytesPerPixel;
// 使用不安全代码块访问指针数据
unsafe
{byte* ptrP = (byte*)pixelsPtr.ToPointer();for (int y = 0; y < height; y++){var offset = y * width;for (int x = 0; x < width; x++){// 计算当前像素的指针位置byte* pixel = ptrP + (offset + x) * bytesPerPixel;// 累加各通道的值sumB += pixel[0];   // 蓝色通道sumG += pixel[1];  // 绿色通道sumR += pixel[2];    // 红色通道}}
}
sw.Stop();sw1 = Stopwatch.StartNew();
// 定义锁定区域
Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
// 锁定位图的指定区域
BitmapData bmpData = bitmap.LockBits(rect, ImageLockMode.ReadOnly, bitmap.PixelFormat);// 获取指向第一个像素数据的指针
IntPtr ptr = bmpData.Scan0;// 判断像素格式,以确保正确处理像素数据
int pixelSize = Image.GetPixelFormatSize(bitmap.PixelFormat) / 8;totalB = 0;
totalG = 0;
totalR = 0;// 使用不安全代码块访问指针数据
unsafe
{byte* ptrP = (byte*)ptr.ToPointer();for (int y = 0; y < height; y++){var offset = y * width;for (int x = 0; x < width; x++){// 计算当前像素的指针位置byte* pixel = ptrP + (offset + x) * bytesPerPixel;// 累加各通道的值totalB+= pixel[0];   // 蓝色通道totalG+= pixel[1];  // 绿色通道totalR += pixel[2];    // 红色通道}}
}            
// 解锁位图
bitmap.UnlockBits(bmpData);
sw.Stop();
#endregion
  1. 分别显示耗时
canvas.DrawText("指针访问 对比:", xOffset, yOffset, paint);
yOffset += paint.FontSpacing;
canvas.DrawText($"SKBitmap 指针访问耗时:{sw.ElapsedMilliseconds}ms,R:{sumR},G:{sumG},B:{sumB}", xOffset, yOffset, paint);
yOffset += paint.FontSpacing;
canvas.DrawText($"Bitmap 指针访问耗时:{sw1.ElapsedMilliseconds}ms,R:{totalR},G:{totalG},B:{totalB}", xOffset, yOffset, paint);
yOffset += paint.FontSpacing;canvas.DrawBitmap(skBmp,new SKRect(xOffset,yOffset,xOffset+400,yOffset+400), paint);
paint.Dispose();

效率对比

对比结果

SKBitmap的GetPixel对Bitmap的GetPixel快3倍左右,两个对象的指针访问方式性能一样,比GetPixel方法快几十、上百倍。

构造函数

SKBitmap()

public SKBitmap ();

构造一个0x0的图像,ColorType为Unknown,未分配内存。

SKBitmap(SKImageInfo)

public SKBitmap (SkiaSharp.SKImageInfo info);

根据指定的SKImageInfo构造位图对象。

var canvas = e.Surface.Canvas;
var info = e.Info;
canvas.Clear(SKColors.White);using (var paint = new SKPaint())
{paint.IsAntialias = true;paint.TextSize = 18F;paint.Typeface = SKTypeface.FromFamilyName("微软雅黑");                var colorTypes = new SKColorType[] { SKColorType.Rgba8888, SKColorType.Gray8 };foreach(var colorType in colorTypes){paint.IsStroke = true;var skImgInfo = new SKImageInfo(200, 100, colorType);var pt = new SKPoint(20F, 20F);using (var sBmp = new SKBitmap(skImgInfo)){canvas.DrawBitmap(sBmp, pt, paint);canvas.DrawRect(new SKRect(pt.X, pt.Y, pt.X + sBmp.Width, pt.Y + sBmp.Height), paint);paint.IsStroke = false;var yOffset = 20 + sBmp.Height + paint.FontSpacing;canvas.DrawText($"SKImageInfo的属性与值", 20, yOffset, paint);// 获取对象的类型信息Type type = skImgInfo.GetType();// 获取所有公共属性PropertyInfo[] properties = type.GetProperties();// 遍历并打印每个属性的名称和值foreach (PropertyInfo property in properties){yOffset += paint.FontSpacing;string name = property.Name;object value = property.GetValue(skImgInfo);if (value == null) value = "null";canvas.DrawText($"{name}:{value}", 20, yOffset, paint);}}canvas.Translate(400, 0);}                
}

分别以SKColorType.Rgba8888和 SKColorType.Gray8创建两幅图像,查看其SKImageInfo各属性的值。
SKImageInfo值

SKBitmap(Int32, Int32, SKColorType, SKAlphaType, SKColorSpace)

public SKBitmap (int width, int height, SkiaSharp.SKColorType colorType, SkiaSharp.SKAlphaType alphaType, SkiaSharp.SKColorSpace colorspace);

创建一个SKBitmap,在SKBitmap上绘制一个圆,再将这个SKBitmap绘制到界面上。

var canvas = e.Surface.Canvas;
var info = e.Info;
canvas.Clear(SKColors.White);using (var paint = new SKPaint())
{paint.IsAntialias = true;paint.TextSize = 18F;paint.Typeface = SKTypeface.FromFamilyName("微软雅黑");// 定义位图的宽度和高度int width = 600;int height = 600;// 定义颜色类型、透明度类型和颜色空间SKColorType colorType = SKColorType.Rgba8888;SKAlphaType alphaType = SKAlphaType.Premul;SKColorSpace colorSpace = SKColorSpace.CreateSrgb();using (var skBmp = new SKBitmap(width, height, colorType, alphaType, colorSpace)){using (var sCanvas = new SKCanvas(skBmp)){paint.Color = SKColors.LightGreen;sCanvas.DrawCircle(skBmp.Width / 2, skBmp.Height / 2, skBmp.Width / 4, paint);}canvas.Translate(100, 100);canvas.DrawBitmap(skBmp, 0, 0, paint);paint.IsStroke = true;canvas.DrawRect(skBmp.Info.Rect, paint);}                   
}

SKBitmap

SKBitmap属性

AlphaType

public SkiaSharp.SKAlphaType AlphaType { get; }

定义了位图像素的透明度处理方式。透明度(或Alpha通道)在图形处理和图像合成中起着关键作用,因为它决定了像素的透明度或不透明度。
不同枚举值的意义:

  1. Unknown:

    • 描述:Alpha 通道的类型未知。这通常用于未明确指定 alpha 类型的图像。
    • 应用场景:较少使用,因为不明确的 alpha 类型会导致不确定的渲染结果。
  2. Opaque:

    • 描述:图像是完全不透明的,没有透明度信息。Alpha 通道的值被忽略。
    • 应用场景:用于不需要处理透明度的图像,提高渲染效率。
  3. Premul (Pre-multiplied alpha):

    • 描述:RGB 值已经被 alpha 通道值预乘,即每个颜色分量已经乘以其对应的 alpha 值。例如,如果 alpha 为 0.5(半透明),则红色分量被乘以 0.5。
    • 应用场景:常用于图像合成,因为这种方式可以简化混合操作,减少计算开销。
  4. Unpremul (Unpremultiplied alpha):

    • 描述:RGB 值没有被 alpha 通道值预乘。颜色和 alpha 是独立存储的。
    • 应用场景:在图像编辑和处理时使用,因为它保留了原始颜色值,适合需要精细调整颜色和透明度的操作。
var canvas = e.Surface.Canvas;
var info = e.Info;
canvas.Clear(SKColors.White);using (var paint = new SKPaint())
{paint.IsAntialias = true;paint.TextSize = 18F;paint.Typeface = SKTypeface.FromFamilyName("微软雅黑");// 定义位图的宽度和高度int width = 150;int height = 150;// 定义颜色类型、透明度类型和颜色空间SKColorType colorType = SKColorType.Rgba8888;var skColors = new SKColor[] { new SKColor(255, 0, 0, 128), new SKColor(0, 255, 0, 128), new SKColor(0, 0, 255, 128) };var skAlphaTypes = new SKAlphaType[] { SKAlphaType.Opaque, SKAlphaType.Premul, SKAlphaType.Unpremul };var pts = new SKPoint[] { new SKPoint(100, 30), new SKPoint(200, 30), new SKPoint(150, 90) };var bmps = new List<SKBitmap>();foreach (var alphaType in skAlphaTypes){var index = 0;var y = 40F;canvas.DrawText($"AlphaType:{alphaType}", 400, y += paint.FontSpacing, paint);foreach (var skColor in skColors){using (var skBmp = new SKBitmap(width, height, colorType, alphaType)){using (var sCanvas = new SKCanvas(skBmp)){paint.Color = skColor;sCanvas.DrawCircle(skBmp.Width / 2, skBmp.Height / 2, skBmp.Width / 2, paint);}canvas.DrawBitmap(skBmp, pts[index++], paint);var color = skBmp.GetPixel(width / 2, height / 2);canvas.DrawText($"R:{color.Red},G:{color.Green},B:{color.Blue},A:{color.Alpha}", 400, y += paint.FontSpacing, paint);}}canvas.Translate(0, 240);}
}

AlphaType

ByteCount

public int ByteCount { get; }

根据RowBytes*Height,返回像素的字节大小。

Bytes

public byte[] Bytes { get; }

获取所有像素数据的副本。

BytesPerPixel

public int BytesPerPixel { get; }

获取每个像素的字节数。如果ColorType为Unknown,则该值为0。

ColorSpace

public SkiaSharp.SKColorSpace ColorSpace { get; }

获取和设置位图的色彩空间。

ColorType

public SkiaSharp.SKColorType ColorType { get; }

获取位图的颜色类型。

DrawsNothing

public bool DrawsNothing { get; }

判断位图是否有影响绘制效果。无效果,返回true,若则返回false。

Info

public SkiaSharp.SKImageInfo Info { get; }

获取具有位图所有属性的 SKImageInfo 实例。

IsEmpty

public bool IsEmpty { get; }

判断位图的尺寸是否为0。
DrawsNothing除了判断尺寸,还判断其它,而IsEmpty只判断尺寸。

IsImmutable

public bool IsImmutable { get; }

判断位图内容是否不可变。
不可变的位图性能更优,可通过SKBitmap对的的SetImmutable()方法设置。

IsNull

public bool IsNull { get; }

直接new SKBitmap()返回true,new SKBitmap(0,0)返回的是false。

Pixels

public SkiaSharp.SKColor[] Pixels { get; set; }

返回所有像素的颜色数组。

ReadyToDraw

public bool ReadyToDraw { get; }

获取位图是否可以有效绘制。

RowBytes

public int RowBytes { get; }

返回每行的字节数。

Width、Height

public int Width { get; }
public int Height { get; }

获取位图的宽与高。

示例

 var canvas = e.Surface.Canvas;var info = e.Info;canvas.Clear(SKColors.White);using (var paint = new SKPaint()){paint.IsAntialias = true;paint.TextSize = 18F;paint.Typeface = SKTypeface.FromFamilyName("微软雅黑");var yOffset = 50F;using (var skBmp0x0 = new SKBitmap(0, 0))using (var skBmp1x1 = new SKBitmap(1, 1)){canvas.DrawText($"0x0SKBitmap,DrawsNothing:{skBmp0x0.DrawsNothing}", 20, yOffset += paint.FontSpacing, paint);canvas.DrawText($"1x1SKBitmap,DrawsNothing:{skBmp1x1.DrawsNothing}", 20, yOffset += paint.FontSpacing, paint);canvas.DrawText($"0x0SKBitmap,IsEmpty:{skBmp0x0.IsEmpty}", 20, yOffset += paint.FontSpacing, paint);canvas.DrawText($"1x1SKBitmap,IsEmpty:{skBmp1x1.IsEmpty}", 20, yOffset += paint.FontSpacing, paint);canvas.DrawText($"0x0SKBitmap,IsNull:{skBmp0x0.IsNull}", 20, yOffset += paint.FontSpacing, paint);canvas.DrawText($"1x1SKBitmap,IsNull:{skBmp1x1.IsNull}", 20, yOffset += paint.FontSpacing, paint);canvas.DrawText($"0x0SKBitmap,ByteCount:{skBmp0x0.ByteCount}", 20, yOffset += paint.FontSpacing, paint);canvas.DrawText($"1x1SKBitmap,ByteCount:{skBmp1x1.ByteCount}", 20, yOffset += paint.FontSpacing, paint);canvas.DrawText($"0x0SKBitmap,BytesPerPixel:{skBmp0x0.BytesPerPixel}", 20, yOffset += paint.FontSpacing, paint);canvas.DrawText($"1x1SKBitmap,BytesPerPixel:{skBmp1x1.BytesPerPixel}", 20, yOffset += paint.FontSpacing, paint);canvas.DrawText($"0x0SKBitmap,IsImmutable:{skBmp0x0.IsImmutable}", 20, yOffset += paint.FontSpacing, paint);canvas.DrawText($"1x1SKBitmap,IsImmutable:{skBmp1x1.IsImmutable}", 20, yOffset += paint.FontSpacing, paint);skBmp1x1.SetImmutable();canvas.DrawText($"1x1SKBitmap,IsImmutable:{skBmp1x1.IsImmutable}", 20, yOffset += paint.FontSpacing, paint);canvas.DrawText($"0x0SKBitmap,RowBytes:{skBmp0x0.RowBytes}", 20, yOffset += paint.FontSpacing, paint);canvas.DrawText($"1x1SKBitmap,RowBytes:{skBmp1x1.RowBytes}", 20, yOffset += paint.FontSpacing, paint);canvas.DrawText($"0x0SKBitmap,Width:{skBmp0x0.Width},Height:{skBmp0x0.Height}", 20, yOffset += paint.FontSpacing, paint);canvas.DrawText($"1x1SKBitmap,Width:{skBmp1x1.Width},Height:{skBmp1x1.Height}", 20, yOffset += paint.FontSpacing, paint);}}

SKBitmap属性相关

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

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

相关文章

“脏读”、“幻读”、“不可重复读”

“脏读”、“幻读”、“不可重复读” 1.概念说明 “脏读”、“幻读”、“不可重复读”是数据库事务的概念。 “脏读”是指一个事务中访问到了另外一个事务未提交的数据。 “不可重复读”是指在一个事务内根据同一个条件对数据进行多次查询&#xff0c;但是结果却不一致&…

C++ Vector的模拟实现

vector的介绍 1. vector是表示可变大小数组的序列容器。 2. 就像数组一样&#xff0c;vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问&#xff0c;和数组一样高效。但是又不像数组&#xff0c;它的大小是可以动态改变的&#xff0c;而…

人形机器人背后的关键技术之一:人体姿态估计WHAM与手势估计HaMeR

前言 本文一开始是属于此文的&#xff0c;但由于人体姿态估计WHAM与手势估计HaMeR比较重要&#xff0c;故导致越写越长&#xff0c;故独立抽取出来成为本文了 第一部分 姿态估计之 WHAM 1.1 WHAM的整体架构 根据arXiv的记录&#xff0c;此篇论文WHAM: Reconstructing World-…

Apple - Advanced Memory Management Programming Guide 内存管理

翻译整理自&#xff1a;Advanced Memory Management Programming Guide&#xff08;Updated: 2012-07-17 https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html#//apple_ref/doc/uid/10000011i 文章目录 一、关于…

异步FIFO

目录 描述 输入描述&#xff1a; 输出描述&#xff1a; 参考代码 描述 请根据题目中给出的双口RAM代码和接口描述&#xff0c;实现异步FIFO&#xff0c;要求FIFO位宽和深度参数化可配置。 电路的接口如下图所示。 双口RAM端口说明&#xff1a; 端口名 I/O 描述 wclk i…

LQR 控制算法应用分析

参考 Optimization Based Control 从基础到复杂地介绍最优控制理论 麻省理工大学机器人算法第八章 LQR 大概说了 lqr 的推导过程&#xff0c;主页有更多算法介绍 wiki LQR 控制器 LQR 多种公式说明 Formulas for discrete time LQR, LQG, LEQG and minimax LQG optimal con…

Springboot项目ES报异常query_shard_exception

详细异常信息如下&#xff1a; {"error": {"root_cause": [{"type": "query_shard_exception","reason": "failed to create query: {\n \"bool\" : {\n \"filter\" : [\n {\n \…

换电脑后导入git本地仓库记录

导入本地仓库tig记录 换了新电脑&#xff0c;将旧电脑的数据盘查到新的笔记本之后发现&#xff0c;使用pycharm 读取不到本地的git提交记录了&#xff0c;我没有将本地git上传到远程仓库的习惯&#xff0c;这可抓马了&#xff0c;硬盘插回去的话也太麻烦了。试了 vscode 提示设…

Vue77-编程式路由

一、需求 不写<router-link>实行路由的跳转。 因为<router-link>的本质是<a>&#xff0c;但是&#xff0c;有时&#xff0c;导航不一定是a标签&#xff01;或者&#xff0c;有时需要等一段时间&#xff0c;页面才跳转。 二、代码实现 三、小结

Wakelocks 框架设计与实现

Wakelocks 框架是基于Wakeup Source实现的为Android系统上层提供投票机制&#xff0c;以阻止系统进入休眠。 1.功能说明 该模块的支持受宏CONFIG_PM_WAKELOCKS控制。在使能该宏的情况下&#xff0c;PM Core初始化过程中会在sysfs下创建两个属性节点&#xff1a; /sys/power/w…

Gradle学习-1

1、APK构建流程 2、Gradle的安装 &#xff08;1&#xff09;安装Java JDK JAVA JDK 下载地址下载安装后需要配置环境变量gradle是运行在Java虚拟机上的&#xff0c;所以需要配置Java JDK &#xff08;2&#xff09;安装 Gradle Gradle下载官网下载安装后需要配置环境变量 …

vscode创建编辑markdown文件

Markdown 是一种轻量级标记语言, 它允许人们使用易读易写的纯文本格式编写文档&#xff0c;然后转换成有效的 XHTML&#xff08;或者HTML&#xff09;文档。 由于 Markdown 的轻量化、易读易写特性&#xff0c;并且对于图片&#xff0c;图表、数学式都有支持&#xff0c;许多网…

[保姆级教程]uniapp配置vueX

文章目录 注意新建文件简单的使用 注意 uniapp是支持vueX的只需配置一下就好 新建文件 在src文件中&#xff0c;新建一个store&#xff08;如果有的话跳过&#xff09; 在store中新建一个js文件&#xff0c;修改js文件名称和选择模板为default 在 uni-app 项目根目录下&…

Vue80-全局路由守卫:前置、后置

一、路由守卫的定义 二、需求 在第三步&#xff0c;做校验&#xff01; 三、代码实现 3-1、前置路由守卫 注意&#xff0c;此时就不能将router一开始就暴露出去了&#xff01; to和from是路由组件的信息。 写法一&#xff1a; 写法二&#xff1a; 缺点&#xff1a;若是路由…

51单片机STC89C52RC——6.2 定时器

一&#xff0c;定时器介绍 STC89C51RC/RD系列单片机的定时器0和定时器1&#xff0c;与传统8051的定时器完全兼容&#xff0c;当在定时器1做波特率发生器时&#xff0c;定时器0可以当两个8位定时器用。 STC89C51RC/RD系列单片机内部设置的两个16位定时器/计数器TO和T1都…

“论数据访问层设计技术及其应用”必过范文,软考高级,系统架构设计师论文

论文真题 在信息系统的开发与建设中,分层设计是一种常见的架构设计方法,区分层次的目的是为了实现“高内聚低耦合”的思想。分层设计能有效简化系统复杂性,使设计结构清晰,便于提高复用能力和产品维护能力。一种常见的层次划分模型是将信息系统分为表现层、业务逻辑层和数…

laravel8框架windows下安装运行

目录 1、安装前如果未安装先安装Composer 2、使用composer安装laravel8 3、使用内置服务器:8000 的命令去访问测试 ​4、使用本地环境运行phpstudy配置到public目录下 Laravel官网 Laravel 中文网 为 Web 工匠创造的 PHP 框架 安装 | 入门指南 |《Laravel 8 中文文档 8.x…

[数据集][图像分类]瑜伽动作分类数据集1238张5类别

数据集类型&#xff1a;图像分类用&#xff0c;不可用于目标检测无标注文件 数据集格式&#xff1a;仅仅包含jpg图片&#xff0c;每个类别文件夹下面存放着对应图片 图片数量(jpg文件个数)&#xff1a;1238 分类类别数&#xff1a;5 类别名称:["downdog","godde…

聊聊贪心算法

第1部分&#xff1a;引言 贪心算法是一种在每一步选择中都采取当前状态下最优&#xff08;或最有利&#xff09;的选择&#xff0c;从而希望导致结果是全局最优的算法策略。这种算法简单、直观&#xff0c;且在很多情况下能够快速得到一个足够好的解决方案。然而&#xff0c;值…

el-upload 组件上传文件(查询,上传,删除,下载功能)

1.html el-upload中的属性&#xff1a; <el-upload ref"upload" class"upload-demo" // element-ui自带的样式 :headers"headerOdj" // 文件上传的头,带token&#xff08;重要&#xff0c;不然传输大文件会断掉&…