android之图片选择器--pictureselector

推荐一个安卓图片/视频/文件选择器。简单好用。
不多废话。直接上代码:

首先,添加依赖:

	//图片选择器api 'io.github.lucksiege:pictureselector:v3.11.1'//图片压缩api 'io.github.lucksiege:compress:v3.11.1'//图片裁剪api 'io.github.lucksiege:ucrop:v3.11.1'//自定义相机api 'io.github.lucksiege:camerax:v3.11.1'api 'com.github.bumptech.glide:glide:4.12.0'

这些依赖是必须的。其次是封装一下,方便后续使用
首先,创建 VideoThumbListener.java:

public class VideoThumbListener implements OnVideoThumbnailEventListener {private Context context;public VideoThumbListener(Context context) {this.context = context;}@Overridepublic void onVideoThumbnail(Context context, String videoPath, OnKeyValueResultCallbackListener call) {Glide.with(context).asBitmap().sizeMultiplier(0.6F).load(videoPath).into(new CustomTarget<Bitmap>() {@Overridepublic void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {ByteArrayOutputStream stream = new ByteArrayOutputStream();resource.compress(Bitmap.CompressFormat.JPEG, 60, stream);FileOutputStream fos = null;String result = null;try {File targetFile = new File(getVideoThumbnailDir(), "thumbnails_" + System.currentTimeMillis() + ".jpg");fos = new FileOutputStream(targetFile);fos.write(stream.toByteArray());fos.flush();result = targetFile.getAbsolutePath();} catch (IOException e) {e.printStackTrace();} finally {PictureFileUtils.close(fos);PictureFileUtils.close(stream);}if (call != null) {call.onCallback(videoPath, result);}}@Overridepublic void onLoadCleared(@Nullable Drawable placeholder) {if (call != null) {call.onCallback(videoPath, "");}}});}private String getVideoThumbnailDir() {File externalFilesDir = context.getExternalFilesDir("");File customFile = new File(externalFilesDir.getAbsolutePath(), "Thumbnail");if (!customFile.exists()) {customFile.mkdirs();}return customFile.getAbsolutePath() + File.separator;}
}

再次就是图片加载器的封装:GlideUtils:


public class GlideUtils implements ImageEngine {/*** 加载图片** @param context   上下文* @param url       资源url* @param imageView 图片承载控件*/@Overridepublic void loadImage(Context context, String url, ImageView imageView) {if (!ActivityCompatHelper.assertValidRequest(context)) {return;}Glide.with(context).load(url)// .error(R.mipmap.icon_photo_error).into(imageView);}/*** 加载图片** @param context    上下文* @param url        资源url* @param imageView  图片承载控件* @param errorImage 图片加载失败资源文件*/public void loadImage(Context context, String url, ImageView imageView, int errorImage) {if (!ActivityCompatHelper.assertValidRequest(context)) {return;}Glide.with(context).load(url).error(errorImage).into(imageView);}@Overridepublic void loadImage(Context context, ImageView imageView, String url, int maxWidth, int maxHeight) {if (!ActivityCompatHelper.assertValidRequest(context)) {return;}Glide.with(context).load(url)
//                .error(R.mipmap.ic_launcher).override(maxWidth, maxHeight).into(imageView);}/*** 加载相册目录封面** @param context   上下文* @param url       图片路径* @param imageView 承载图片ImageView*/@Overridepublic void loadAlbumCover(Context context, String url, ImageView imageView) {if (!ActivityCompatHelper.assertValidRequest(context)) {return;}Glide.with(context).asBitmap().load(url)
//                .error(R.mipmap.ic_launcher).override(180, 180).sizeMultiplier(0.5f).transform(new CenterCrop(), new RoundedCorners(8))
//                .placeholder(R.mipmap.ic_launcher).into(imageView);}/*** 默认图片** @param context* @param url* @param imageView*/public void loadVideoThumb(Context context, String url, ImageView imageView) {loadVideoThumb(context, url, 0, imageView);}public void loadVideoThumb(Context context, String url, int errorImage, ImageView imageView) {Glide.with(context).setDefaultRequestOptions(new RequestOptions().frame(1000000).centerCrop().error(errorImage).placeholder(errorImage)).load(url).into(imageView);}/*** 获取视频第一证* @param path 文件路径* @return*/public Bitmap loadVideoThumb(String path) {MediaMetadataRetriever media = new MediaMetadataRetriever();media.setDataSource(path);return media.getFrameAtTime();}/*** 加载图片列表图片** @param context   上下文* @param url       图片路径* @param imageView 承载图片ImageView*/@Overridepublic void loadGridImage(Context context, String url, ImageView imageView) {if (!ActivityCompatHelper.assertValidRequest(context)) {return;}Glide.with(context).load(url).override(200, 200).centerCrop()
//                .error(R.mipmap.ic_launcher)
//                .placeholder(R.mipmap.ic_launcher).into(imageView);}@Overridepublic void pauseRequests(Context context) {Glide.with(context).pauseRequests();}@Overridepublic void resumeRequests(Context context) {Glide.with(context).resumeRequests();}private GlideUtils() {}private static final class InstanceHolder {static final GlideUtils instance = new GlideUtils();}public static GlideUtils createGlideEngine() {return InstanceHolder.instance;}
}

最后。就是正题了,PictureUtils.java:

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.provider.MediaStore;
import android.widget.ImageView;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.transition.Transition;
import com.luck.lib.camerax.SimpleCameraX;
import com.luck.picture.lib.basic.PictureSelector;
import com.luck.picture.lib.config.PictureMimeType;
import com.luck.picture.lib.config.SelectMimeType;
import com.luck.picture.lib.engine.CompressFileEngine;
import com.luck.picture.lib.engine.CropFileEngine;
import com.luck.picture.lib.engine.VideoPlayerEngine;
import com.luck.picture.lib.entity.LocalMedia;
import com.luck.picture.lib.entity.MediaExtraInfo;
import com.luck.picture.lib.interfaces.OnCameraInterceptListener;
import com.luck.picture.lib.interfaces.OnExternalPreviewEventListener;
import com.luck.picture.lib.interfaces.OnRecordAudioInterceptListener;
import com.luck.picture.lib.interfaces.OnResultCallbackListener;
import com.luck.picture.lib.permissions.PermissionChecker;
import com.luck.picture.lib.permissions.PermissionResultCallback;
import com.luck.picture.lib.utils.MediaUtils;
import com.luck.picture.lib.utils.ToastUtils;
import com.yalantis.ucrop.UCrop;
import com.yalantis.ucrop.UCropImageEngine;import java.io.File;
import java.util.ArrayList;import top.zibin.luban.Luban;
import top.zibin.luban.OnNewCompressListener;/*** @author: zzw* @Description:* @Date: 2022/9/21 21:37*/
public class PictureUtils {/*** 打开摄像头 拍照** @param context* @param isRotateImage                   true 前置 false 后置* @param onPictureSelectorResultListener 回调*/public static void openCamera(Context context, boolean isRotateImage, OnPictureSelectorResultListener onPictureSelectorResultListener) {openCamera(context, SelectMimeType.ofImage(), isRotateImage, onPictureSelectorResultListener);}/*** 打开摄像头 录制视频** @param context* @param isRotateImage                   true 前置 false 后置* @param onPictureSelectorResultListener 回调*/public static void openVideo(Context context, boolean isRotateImage, OnPictureSelectorResultListener onPictureSelectorResultListener) {openCamera(context, SelectMimeType.ofVideo(), isRotateImage, onPictureSelectorResultListener);}/*** 打开摄像头** @param context                         上下文* @param onPictureSelectorResultListener 回调*/public static void openCamera(Context context, int openCamera, boolean isRotateImage, OnPictureSelectorResultListener onPictureSelectorResultListener) {PictureSelector.create(context).openCamera(openCamera).isCameraAroundState(isRotateImage).setVideoThumbnailListener(new VideoThumbListener(context)).setCompressEngine((CompressFileEngine) (context1, source, call) -> Luban.with(context1).load(source).ignoreBy(100).setCompressListener(new OnNewCompressListener() {@Overridepublic void onStart() {}@Overridepublic void onSuccess(String source, File compressFile) {if (call != null) {call.onCallback(source, compressFile.getAbsolutePath());}}@Overridepublic void onError(String source, Throwable e) {if (call != null) {call.onCallback(source, null);}}}).launch()).forResult(new OnResultCallbackListener<LocalMedia>() {@Overridepublic void onResult(ArrayList<LocalMedia> result) {onPictureSelectorResultListener.onResult(result);}@Overridepublic void onCancel() {}});}/*** 设置头像** @param mContext* @param selectResult                    结果* @param onPictureSelectorResultListener 结果回调*/public static void createAvatar(Context mContext, ArrayList<LocalMedia> selectResult, OnPictureSelectorResultListener onPictureSelectorResultListener) {create(mContext, SelectMimeType.ofImage(), selectResult, 1, 1, true, onPictureSelectorResultListener);}/*** 选择单张图片** @param mContext* @param selectResult                    结果* @param onPictureSelectorResultListener 结果回调*/public static void createImageMin(Context mContext, ArrayList<LocalMedia> selectResult, OnPictureSelectorResultListener onPictureSelectorResultListener) {create(mContext, SelectMimeType.ofImage(), selectResult, 1, 1, false, onPictureSelectorResultListener);}/*** 选择多张图片** @param mContext* @param selectResult                    结果* @param selectMax                       最多选择* @param onPictureSelectorResultListener 结果回调*/public static void createImageMax(Context mContext, int selectMax, ArrayList<LocalMedia> selectResult, OnPictureSelectorResultListener onPictureSelectorResultListener) {create(mContext, SelectMimeType.ofImage(), selectResult, 1, selectMax, false, onPictureSelectorResultListener);}/*** 选择单个视频** @param mContext* @param selectResult                    结果* @param onPictureSelectorResultListener 结果回调*/public static void createVideo(Context mContext, ArrayList<LocalMedia> selectResult, OnPictureSelectorResultListener onPictureSelectorResultListener) {create(mContext, SelectMimeType.ofVideo(), selectResult, 1, 1, false, onPictureSelectorResultListener);}/*** 选择单个音频** @param mContext* @param selectResult                    结果* @param onPictureSelectorResultListener 结果回调*/public static void createAudio(Context mContext, ArrayList<LocalMedia> selectResult, OnPictureSelectorResultListener onPictureSelectorResultListener) {create(mContext, SelectMimeType.ofAudio(), selectResult, 1, 1, false, onPictureSelectorResultListener);}/*** 选择 媒体 图片 视频 音频** @param mContext* @param selectResult                    结果* @param onPictureSelectorResultListener 结果回调*/public static void createPicture(Context mContext, ArrayList<LocalMedia> selectResult, OnPictureSelectorResultListener onPictureSelectorResultListener) {create(mContext, SelectMimeType.ofAll(), selectResult, 1, 1, false, onPictureSelectorResultListener);}/*** 默认设置** @param mContext* @param selectMimeType                  结果* @param selectResult                    结果* @param selectMin                       最少选择* @param selectMax                       最多选择* @param isCrop                          是否剪裁* @param onPictureSelectorResultListener 结果回到*/public static void create(Context mContext, int selectMimeType, ArrayList<LocalMedia> selectResult, int selectMin, int selectMax, boolean isCrop, OnPictureSelectorResultListener onPictureSelectorResultListener) {PictureSelector.create(mContext).openGallery(selectMimeType).setMaxSelectNum(selectMax).setCropEngine(getCropFileEngine(isCrop)).setMinSelectNum(selectMin).setFilterVideoMaxSecond(selectMimeType == SelectMimeType.ofVideo() ? 60 : 60 * 10).setFilterVideoMinSecond(5).setRecordVideoMaxSecond(selectMimeType == SelectMimeType.ofVideo() ? 60 : 60 * 10).setRecordVideoMinSecond(5).setFilterMaxFileSize(100 * 1024 * 1024).setCameraInterceptListener(new MeOnCameraInterceptListener()).isFilterSizeDuration(true).setSelectedData(selectResult).setRecordAudioInterceptListener(new MeOnRecordAudioInterceptListener()).setCompressEngine((CompressFileEngine) (context, source, call) -> Luban.with(context).load(source).ignoreBy(100).setCompressListener(new OnNewCompressListener() {@Overridepublic void onStart() {}@Overridepublic void onSuccess(String source, File compressFile) {if (call != null) {call.onCallback(source, compressFile.getAbsolutePath());}}@Overridepublic void onError(String source, Throwable e) {if (call != null) {call.onCallback(source, null);}}}).launch()).setImageEngine(GlideUtils.createGlideEngine()).forResult(new OnResultCallbackListener<LocalMedia>() {@Overridepublic void onResult(ArrayList<LocalMedia> result) {for (LocalMedia media : result) {if (media.getWidth() == 0 || media.getHeight() == 0) {if (PictureMimeType.isHasImage(media.getMimeType())) {MediaExtraInfo imageExtraInfo = MediaUtils.getImageSize(mContext, media.getPath());media.setWidth(imageExtraInfo.getWidth());media.setHeight(imageExtraInfo.getHeight());} else if (PictureMimeType.isHasVideo(media.getMimeType())) {MediaExtraInfo videoExtraInfo = MediaUtils.getVideoSize(mContext, media.getPath());media.setWidth(videoExtraInfo.getWidth());media.setHeight(videoExtraInfo.getHeight());}}
//                            LogUtils.e("文件名: " + media.getFileName() + "\n" +
//                                    "是否压缩:" + media.isCompressed() + "\n" +
//                                    "压缩路径:" + media.getCompressPath() + "\n" +
//                                    "初始路径:" + media.getPath() + "\n" +
//                                    "绝对路径:" + media.getRealPath() + "\n" +
//                                    "是否裁剪:" + media.isCut() + "\n" +
//                                    "裁剪路径:" + media.getCutPath() + "\n" +
//                                    "是否开启原图:" + media.isOriginal() + "\n" +
//                                    "原图路径:" + media.getOriginalPath() + "\n" +
//                                    "沙盒路径:" + media.getSandboxPath() + "\n" +
//                                    "水印路径:" + media.getWatermarkPath() + "\n" +
//                                    "视频缩略图:" + media.getVideoThumbnailPath() + "\n" +
//                                    "原始宽高: " + media.getWidth() + "x" + media.getHeight() + "\n" +
//                                    "裁剪宽高: " + media.getCropImageWidth() + "x" + media.getCropImageHeight() + "\n" +
//                                    "文件大小: " + PictureFileUtils.formatAccurateUnitFileSize(media.getSize()) + "\n" +
//                                    "文件大小: " + media.getSize() + "\n" +
//                                    "文件时长: " + media.getDuration()
//                            );}onPictureSelectorResultListener.onResult(result);}@Overridepublic void onCancel() {}});}/*** 查看图片大图** @param mContext* @param position* @param localMedia*/public static void openImage(Context mContext, int position, ArrayList<LocalMedia> localMedia) {PictureSelector.create(mContext).openPreview().isHidePreviewDownload(true).setImageEngine(GlideUtils.createGlideEngine()).setExternalPreviewEventListener(new OnExternalPreviewEventListener() {@Overridepublic void onPreviewDelete(int position) {}@Overridepublic boolean onLongPressDownload(Context context, LocalMedia media) {return false;}}).startActivityPreview(position, false, localMedia);}public static void openImage(Context mContext, int position, String imageUrl) {ArrayList<LocalMedia> localMedia = new ArrayList<>();for (String url : imageUrl.split(",")) {localMedia.add(LocalMedia.generateHttpAsLocalMedia(url));}PictureSelector.create(mContext).openPreview().setImageEngine(GlideUtils.createGlideEngine()).setExternalPreviewEventListener(new OnExternalPreviewEventListener() {@Overridepublic void onPreviewDelete(int position) {}@Overridepublic boolean onLongPressDownload(Context context, LocalMedia media) {return false;}}).startActivityPreview(position, false, localMedia);}/*** 预览视频** @param mContext* @param position* @param localMedia*/public static void openVideo(Context mContext, int position, ArrayList<LocalMedia> localMedia) {openVideo(mContext, position, localMedia, null);}/*** 预览视频** @param mContext* @param position* @param localMedia*/public static void openVideo(Context mContext, int position, ArrayList<LocalMedia> localMedia, VideoPlayerEngine videoPlayerEngine) {PictureSelector.create(mContext).openPreview().setImageEngine(GlideUtils.createGlideEngine()).setVideoPlayerEngine(videoPlayerEngine).isAutoVideoPlay(true).setExternalPreviewEventListener(new OnExternalPreviewEventListener() {@Overridepublic void onPreviewDelete(int position) {}@Overridepublic boolean onLongPressDownload(Context context, LocalMedia media) {return false;}}).startActivityPreview(position, false, localMedia);}/*** 裁剪引擎** @return*/private static ImageFileCropEngine getCropFileEngine(boolean isCrop) {return isCrop ? new ImageFileCropEngine() : null;}/*** 自定义裁剪*/private static class ImageFileCropEngine implements CropFileEngine {@Overridepublic void onStartCrop(Fragment fragment, Uri srcUri, Uri destinationUri, ArrayList<String> dataSource, int requestCode) {UCrop.Options options = buildOptions();UCrop uCrop = UCrop.of(srcUri, destinationUri, dataSource);uCrop.withOptions(options);uCrop.setImageEngine(new UCropImageEngine() {@Overridepublic void loadImage(Context context, String url, ImageView imageView) {Glide.with(context).load(url).override(180, 180).into(imageView);}@Overridepublic void loadImage(Context context, Uri url, int maxWidth, int maxHeight, OnCallbackListener<Bitmap> call) {Glide.with(context).asBitmap().load(url).override(maxWidth, maxHeight).into(new CustomTarget<Bitmap>() {@Overridepublic void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {if (call != null) {call.onCall(resource);}}@Overridepublic void onLoadCleared(@Nullable Drawable placeholder) {if (call != null) {call.onCall(null);}}});}});uCrop.start(fragment.requireActivity(), fragment, requestCode);}}/*** 配制UCrop,可根据需求自我扩展** @return*/private static UCrop.Options buildOptions() {UCrop.Options options = new UCrop.Options();options.setHideBottomControls(true);options.setFreeStyleCropEnabled(true);options.setShowCropFrame(true);options.setShowCropGrid(false);options.setCircleDimmedLayer(false);options.withAspectRatio(1, 1);options.isCropDragSmoothToCenter(false);options.setMaxScaleMultiplier(100);return options;}public interface OnPictureSelectorResultListener {void onResult(ArrayList<LocalMedia> result);}/*** 自定义拍照*/private static class MeOnCameraInterceptListener implements OnCameraInterceptListener {@Overridepublic void openCamera(Fragment fragment, int cameraMode, int requestCode) {SimpleCameraX camera = SimpleCameraX.of();camera.isAutoRotation(true);camera.setCameraMode(cameraMode);camera.setVideoFrameRate(50);camera.setVideoBitRate(5 * 1024 * 1024);camera.isDisplayRecordChangeTime(true);camera.isManualFocusCameraPreview(true);camera.isZoomCameraPreview(true);camera.setImageEngine((context, url, imageView) -> Glide.with(context).load(url).into(imageView));camera.start(fragment.requireActivity(), fragment, requestCode);}}/*** 录音回调事件*/private static class MeOnRecordAudioInterceptListener implements OnRecordAudioInterceptListener {@Overridepublic void onRecordAudio(Fragment fragment, int requestCode) {String[] recordAudio = {Manifest.permission.RECORD_AUDIO};if (PermissionChecker.isCheckSelfPermission(fragment.getContext(), recordAudio)) {startRecordSoundAction(fragment, requestCode);} else {PermissionChecker.getInstance().requestPermissions(fragment, new String[]{Manifest.permission.RECORD_AUDIO}, new PermissionResultCallback() {@Overridepublic void onGranted() {startRecordSoundAction(fragment, requestCode);}@Overridepublic void onDenied() {}});}}}/*** 启动录音意图** @param fragment* @param requestCode*/private static void startRecordSoundAction(Fragment fragment, int requestCode) {Intent recordAudioIntent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);if (recordAudioIntent.resolveActivity(fragment.requireActivity().getPackageManager()) != null) {fragment.startActivityForResult(recordAudioIntent, requestCode);} else {ToastUtils.showToast(fragment.getContext(), "The system is missing a recording component");}}
}

至于封装,到此就结束了。最后看一下用法,举例::

打开相机:

PictureUtils.openCamera(this,false){val localMedia = it[0]
}

选择X张照片:

PictureUtils.createImageMax(this, 9, arrayListOf<LocalMedia>()){it.forEach { section ->// section.realPath:获取图片路径}
}

就简单列举两个。剩下的都差不多。
使用的时候别忘记添加权限哟。

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

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

相关文章

Springboot3+vue3从0到1开发实战项目(一)

一. 可以在本项目里面自由发挥拓展 二. 知识整合项目使用到的技术 后端开发 &#xff1a; Validation, Mybatis,Redis, Junit,SpringBoot3 &#xff0c;mysql&#xff0c;Swagger, JDK17 &#xff0c;项目部署 前端开发&#xff1a; Vue3&#xff0c;Vite&#xff0c;Router…

Java数组和集合

在Java中&#xff0c;数组和集合是两个重要的概念&#xff0c;它们用于存储和操作数据。本文将详细介绍Java中的数组和集合&#xff0c;包括它们的定义、初始化、访问和常见操作 一、数组&#xff08;Array&#xff09; 数组是一种用于存储相同类型数据的容器&#xff0c;它可…

DNS的各种进阶新玩法

你们好&#xff0c;我的网工朋友&#xff0c;今天和你聊聊DNS。 01 什么是DNS&#xff1f; mac地址诞生&#xff0c;可是太不容易记忆了&#xff0c;出现了简化了IP形式&#xff0c;它被直接暴露给外网不说&#xff0c;还让人类还是觉得比较麻烦&#xff0c;干脆用几个字母算了…

【Git】一文教你学会 submodule 的增、删、改、查

添加子模块 $ git submodule add <url> <path>url 为想要添加的子模块路径path 为子模块存放的本地路径 示例&#xff0c;添加 r-tinymaix 为子模块到主仓库 ./sdk/packages/online-packages/r-tinymaix 路径下&#xff0c;命令如下所示&#xff1a; $ git subm…

用自己热爱的事赚钱,是多么的幸福

挖掘天赋可能有些困难&#xff0c;但挖掘爱好就简单多啦&#xff01;最幸福的事情就是能用自己喜欢的事情赚钱。 我们要说的是一个博主&#xff0c;他非常喜欢骑自行车&#xff0c;虽然他的工作是在外贸公司做销售&#xff0c;但每当有空时&#xff0c;他都会骑自行车。而且他…

Nginx同时支持Http和Https的配置详解

当配置Nginx同时支持HTTP和HTTPS时&#xff0c;需要进行以下步骤&#xff1a; 安装和配置SSL证书&#xff1a; 获得SSL证书&#xff1a;从可信任的证书颁发机构&#xff08;CA&#xff09;或使用自签名证书创建SSL证书。 将证书和私钥保存到服务器&#xff1a;将SSL证书和私钥…

spring 的事务隔离;Spring框架的事务管理的优点

文章目录 说一下 spring 的事务隔离&#xff1f;Spring框架的事务管理有哪些优点&#xff1f;你更倾向用哪种事务管理类型&#xff1f; 聊一聊spring事务的隔离&#xff0c;事务的隔离对于一个系统来说也是非常重要的&#xff0c;直接上干货&#xff01;&#xff01;&#xff0…

Python与设计模式--享元模式

10-Python与设计模式–享元模式 一、网上咖啡选购平台 假设有一个网上咖啡选购平台&#xff0c;客户可以在该平台上下订单订购咖啡&#xff0c;平台会根据用户位置进行 线下配送。假设其咖啡对象构造如下&#xff1a; class Coffee:name price 0def __init__(self,name):se…

Go iota简介

当声明枚举类型或定义一组相关常量时&#xff0c;Go语言中的iota关键字可以帮助我们简化代码并自动生成递增的值。本文档将详细介绍iota的用法和行为。 iota关键字 iota是Go语言中的一个预定义标识符&#xff0c;它用于创建自增的无类型整数常量。iota的行为类似于一个计数器…

数据库基础入门 — SQL排序与分页

我是南城余&#xff01;阿里云开发者平台专家博士证书获得者&#xff01; 欢迎关注我的博客&#xff01;一同成长&#xff01; 一名从事运维开发的worker&#xff0c;记录分享学习。 专注于AI&#xff0c;运维开发&#xff0c;windows Linux 系统领域的分享&#xff01; 本…

[深度理解] 重启 Splunk Search Head Cluster

1: 背景: 关于释放Splunk search head 的job 运行压力:splunk search head cluster 要重启的话,怎么办? 答案是:splunk rolling-restart shcluster-members Initiate a rolling restart from the command line Invoke the splunk rolling-restart command from any me…

3款免费次数多且功能又强大的国产AI绘画工具

hi&#xff0c;同学们&#xff0c;本期是我们第55 期 AI工具教程 最近两个月&#xff0c;国内很多AI绘画软件被关停&#xff0c;国外绝大部分AI绘画工具费用不低&#xff0c;因此 这两天我 重新整理 国产 AI绘画 工具 &#xff0c; 最终 筛选了 3款功能强大&#xf…

LeeCode前端算法基础100题(3)- N皇后

一、问题详情&#xff1a; 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff0c;返回所有不同的 n 皇后…

虚拟机系列:vmware和Oracle VM VirtualBox虚拟机的区别,简述哪一个更适合我?以及相互转换

一. VMware和Oracle VM VirtualBox虚拟机的区别主要体现在以下几个方面: 首先两种软件的安装使用教程如下: VMware ESXI 安装使用教程 Oracle VM VirtualBox安装使用教程 商业模式:VMware是一家商业公司,而Oracle VM VirtualBox是开源软件; 功能:VMware拥有更多的功能和…

Leetcode200. 岛屿数量

Every day a Leetcode 题目来源&#xff1a;200. 岛屿数量 解法1&#xff1a;深度优先搜索 设目前指针指向一个岛屿中的某一点 (i, j)&#xff0c;寻找包括此点的岛屿边界。 从 (i, j) 向此点的上下左右 (i1,j)&#xff0c;(i-1,j)&#xff0c;(i,j1)&#xff0c;(i,j-1) …

“圆柱-计算公式“技术支持网址

该软件可以计算圆柱的底面圆周长、底面积、侧面积和体积。 您在使用中有遇到任何问题都可以和我们联系。我们会在第一时间回复您。 邮箱地址&#xff1a;elmo30zeongmail.com 谢谢&#xff01;

如何将本地websocket发布至公网并实现远程访问?

本地websocket服务端暴露至公网访问【cpolar内网穿透】 文章目录 本地websocket服务端暴露至公网访问【cpolar内网穿透】1. Java 服务端demo环境2. 在pom文件引入第三包封装的netty框架maven坐标3. 创建服务端,以接口模式调用,方便外部调用4. 启动服务,出现以下信息表示启动成功…

VR云游:让旅游产业插上数字化翅膀,打造地方名片

自多地入冬降温以来&#xff0c;泡温泉成了许多人周末度假的选择&#xff0c;在气温持续走低的趋势下&#xff0c;温泉游也迎来了旺季&#xff1b;但是依旧有些地区温度依旧温暖&#xff0c;例如南京的梧桐美景也吸引了不少游客前去打卡&#xff0c;大家穿着汉服与金黄的树叶合…

【AI考证笔记】NO.1人工智能的基础概念

以下部分内容来自于百度智能云人才认证培训讲义&#xff0c;腾讯等也有人工智能类似的讲义&#xff0c;限时免费&#xff0c;也就是不报考&#xff0c;也能系统学习&#xff0c;课程做的都是不错的。有感兴趣的朋友&#xff0c;可以去检索学习。 本系列是学习笔记&#xff0c;…

6个常用的聚类评价指标

评估聚类结果的有效性&#xff0c;即聚类评估或验证&#xff0c;对于聚类应用程序的成功至关重要。它可以确保聚类算法在数据中识别出有意义的聚类&#xff0c;还可以用来确定哪种聚类算法最适合特定的数据集和任务&#xff0c;并调优这些算法的超参数(例如k-means中的聚类数量…