libVLC 视频抓图
Windows操作系统提供了多种便捷的截图方式,常见的有以下几种:
- 全屏截图:通过按下PrtSc键(Print Screen),可以截取整个屏幕的内容。截取的图像会保存在剪贴板中,可以通过Ctrl+V粘贴到图片编辑工具或其他软件的输入框中。
- 当前窗口截图:同时按下Alt + PrtSc键,可以截取当前活动的窗口。同样,截图内容会被保存在剪贴板中。
- 矩形截图:使用快捷键Windows + Shift + S,可以选择矩形截图模式,然后拖动鼠标选取屏幕上的任意矩形区域进行截图。
- 自由形状截图:同样使用Windows + Shift + S快捷键,可以选择任意形状截图模式,允许你自由绘制截图区域的形状。
libVLC 中通过libvlc_video_take_snapshot核心接口来截图。
以下是如何使用 libVLC 设置视频裁剪区域的基本步骤:
1. 初始化 libVLC 和媒体播放器
首先,你需要初始化 libVLC 实例和媒体播放器对象。
#include <vlc/vlc.h>int main(int argc, char* argv[])
{libvlc_instance_t* inst;libvlc_media_player_t* mp;libvlc_media_t* m;// 加载 libVLC 引擎inst = libvlc_new(0, NULL);// 创建一个新的 itemm = libvlc_media_new_location(inst, "your_video_path_here");mp = libvlc_media_player_new_from_media(m);// 不再需要媒体对象libvlc_media_release(m);
}
2. 播放视频
// 播放媒体播放器
libvlc_media_player_play(mp);// 保持程序运行,直到视频播放完成
while (libvlc_media_player_is_playing(mp)) {// 可以在这里加入延时
}// 清理 libVLC
libvlc_media_player_stop(mp);
libvlc_media_player_release(mp);
libvlc_release(inst);return 0;
3.截图
这里为了方便,路径写死了。
if (vlc_mediaPlayer){QString path = "./snap.png";libvlc_video_take_snapshot(vlc_mediaPlayer, 0, path.toUtf8().data(), 0, 0);}
以下是VLC播放器中使用的截图界面,我们仿照这个做一个界面。

以下是效果图。
菜单添加action,并响应槽函数。
m_snapAction = m_videoMenu->addAction("截图");
connect(m_snapAction, &QAction::triggered, this, &showWidget::slotSnap);
槽函数如下图所示,为了方便,路径写死了。
void showWidget::slotSnap()
{if (vlc_mediaPlayer){QString path = "./snap.png";libvlc_video_take_snapshot(vlc_mediaPlayer, 0, path.toUtf8().data(), 0, 0);}
}
生成目录下snap.png。

完整源码:
#pragma once
#define LIBVLC_USE_PTHREAD_CANCEL 1
#include <QtWidgets/QWidget>
#include "ui_showWidget.h"
#include <QMenu>
#include <QActionGroup>
#include <vlc/vlc.h>#include <QDebug>
#include <QFileDialog>
#include <QThread>
#include <QMouseEvent>
#include <QKeyEvent>enum Rate
{Rate2X,Rate1_5X,Rate1_25X,Rate1_0X,Rate0_75X,Rate0_5X
};class showWidget : public QWidget
{Q_OBJECTpublic:showWidget(QWidget *parent = nullptr);~showWidget();protected:virtual void mousePressEvent(QMouseEvent *event);virtual void mouseDoubleClickEvent(QMouseEvent *event);virtual void keyPressEvent(QKeyEvent *event);private slots:void slotOpenFile();void slotPlay();void slotPause();void slotStop();void slotValueChanged(int value);void slotCurrentIndexChanged(int index);void slotActionTriggered(QAction *action);void slotCropActionTriggered(QAction *action);void slotScaleActionTriggered(QAction *action);void slotSnap();private://事件处理回调static void vlcEvents(const libvlc_event_t *ev, void *param);//初始化menuvoid initMenu();private:Ui::showWidgetClass ui;private:libvlc_instance_t *vlc_base = nullptr;libvlc_media_t *vlc_media = nullptr;libvlc_media_player_t *vlc_mediaPlayer = nullptr;QList<float> m_lstRate;QMenu *m_menu = nullptr;QAction *m_video = nullptr;QAction *m_scaleAction = nullptr; //缩放QAction *m_aspectRatioAction = nullptr; //宽高比QAction *m_cropAction = nullptr; //裁剪QAction *m_snapAction = nullptr;//截图QMenu *m_videoMenu = nullptr;//宽高比QMenu *m_aspectRatioMenu = nullptr;QAction *m_default = nullptr;QAction *m_16_9 = nullptr;QAction *m_4_3 = nullptr;QAction *m_1_1 = nullptr;QAction *m_16_10 = nullptr;QAction *m_2_21_1 = nullptr;QAction *m_2_35_1= nullptr;QAction *m_2_38_1 = nullptr;QAction *m_5_4 = nullptr;QActionGroup *m_group = nullptr;QAction *m_preAspectRatio = nullptr;//宽高比//裁剪QMenu *m_cropMenu = nullptr;QAction *m__cropDefault = nullptr;QAction *m__crop16_10 = nullptr;QAction *m__crop16_9 = nullptr;QAction *m__crop4_3 = nullptr;QAction *m__crop1_85_1 = nullptr;QAction *m__crop2_21_1 = nullptr;QAction *m__crop2_35_1 = nullptr;QAction *m__crop2_39_1 = nullptr;QAction *m__crop5_3 = nullptr;QAction *m__crop5_4 = nullptr;QAction *m__crop1_1 = nullptr;QActionGroup *m_cropGroup = nullptr;QAction *m_preCrop= nullptr;//裁剪//缩放QMenu *m_scaleMenu = nullptr;QAction *m_scale1_4 = nullptr;QAction *m_scale1_2 = nullptr;QAction *m_scale1_1 = nullptr;QAction *m_scale2_1 = nullptr;QActionGroup *m_scaleGroup = nullptr;QAction *m_preScale = nullptr;//缩放char *m_defalutRate = nullptr;char *m_defalutCrop = nullptr;float m_defalutScale = 0;
};
cpp
#include "showWidget.h"
#include <QTimer>
#include <QTime>#pragma execution_character_set("utf-8")showWidget::showWidget(QWidget *parent): QWidget(parent)
{ui.setupUi(this);this->setWindowTitle("视频播放器");ui.cbxRate->setCurrentIndex(Rate1_0X);m_lstRate << 2.0 << 1.5 << 1.25 << 1.0 << 0.75 << 0.5;initMenu();ui.btnOpen->setFocusPolicy(Qt::NoFocus);ui.btnPlay->setFocusPolicy(Qt::NoFocus);ui.btnPause->setFocusPolicy(Qt::NoFocus);ui.btnStop->setFocusPolicy(Qt::NoFocus);ui.hSliderVolumn->setFocusPolicy(Qt::NoFocus);ui.cbxRate->setFocusPolicy(Qt::NoFocus);connect(ui.btnOpen, &QPushButton::clicked, this, &showWidget::slotOpenFile);connect(ui.btnPlay, &QPushButton::clicked, this, &showWidget::slotPlay);connect(ui.btnPause, &QPushButton::clicked, this, &showWidget::slotPause);connect(ui.btnStop, &QPushButton::clicked, this, &showWidget::slotStop);connect(ui.btnSnap, &QPushButton::clicked, this, &showWidget::slotSnap);connect(ui.hSliderVolumn, &QSlider::valueChanged, this, &showWidget::slotValueChanged);connect(ui.cbxRate,SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentIndexChanged(int)));
}showWidget::~showWidget()
{libvlc_release(vlc_base); //减少libvlc实例的引用计数,并销毁
}void showWidget::mousePressEvent(QMouseEvent *event)
{switch (event->button()){case Qt::RightButton://this->setWindowState(Qt::WindowMinimized);m_menu->exec(event->globalPos());break;default:QWidget::mousePressEvent(event);}
}void showWidget::mouseDoubleClickEvent(QMouseEvent *event)
{if (this->isFullScreen()){this->showNormal();}else{this->showFullScreen();}
}void showWidget::keyPressEvent(QKeyEvent *event)
{if (!vlc_mediaPlayer)return;int value = ui.hSliderVolumn->value();if (event->key() == Qt::Key_W) //添加音量{qDebug() << "up";slotValueChanged(value+10);}else if (event->key() == Qt::Key_S) //减小音量{slotValueChanged(value - 10);}else if (event->key() == Qt::Key_Space){if (vlc_mediaPlayer && libvlc_media_player_get_state(vlc_mediaPlayer) == libvlc_Playing){libvlc_media_player_pause(vlc_mediaPlayer);}else if (vlc_mediaPlayer && libvlc_media_player_get_state(vlc_mediaPlayer) == libvlc_Paused){libvlc_media_player_play(vlc_mediaPlayer);}}
}void showWidget::slotOpenFile()
{/*选择文件*/QString filename = QFileDialog::getOpenFileName(this, "选择打开的文件", "D:/", tr("*.*"));std::replace(filename.begin(), filename.end(), QChar('/'), QChar('\\'));vlc_base = libvlc_new(0, NULL);vlc_media = libvlc_media_new_path(vlc_base, filename.toUtf8().data());if (!vlc_media) {return;}// 创建libvlc实例和媒体播放器vlc_mediaPlayer = libvlc_media_player_new_from_media(vlc_media);if (!vlc_mediaPlayer) {return;}// 等待元数据加载完成libvlc_media_parse(vlc_media);m_defalutRate = libvlc_video_get_aspect_ratio(vlc_mediaPlayer);m_defalutCrop = libvlc_video_get_crop_geometry(vlc_mediaPlayer);libvlc_video_set_mouse_input(vlc_mediaPlayer, 0);libvlc_video_set_key_input(vlc_mediaPlayer, 0);// 获取各种元数据const char *title = libvlc_media_get_meta(vlc_media, libvlc_meta_Title);const char *artist = libvlc_media_get_meta(vlc_media, libvlc_meta_Artist);const char *album = libvlc_media_get_meta(vlc_media, libvlc_meta_Album);const char *url = libvlc_media_get_meta(vlc_media, libvlc_meta_URL);const char *date = libvlc_media_get_meta(vlc_media, libvlc_meta_Date);const char *lang = libvlc_media_get_meta(vlc_media, libvlc_meta_Language);int duration = libvlc_media_get_duration(vlc_media); // 获取时长(单位:毫秒)qDebug("Title: %s", title ? title : "N/A");qDebug("Artist: %s", artist ? artist : "N/A");qDebug("Album: %s", album ? album : "N/A");qDebug("Duration: %d ms", duration);qDebug("url: %s", url ? url : "N/A");qDebug("date: %s", date ? date : "N/A");qDebug("lang: %s", lang ? lang : "N/A");libvlc_media_track_t **tracks;int track_count = libvlc_media_tracks_get(vlc_media,&tracks);for (unsigned i = 0; i < track_count; i++) {libvlc_media_track_t* track = tracks[i];// 显示轨道信息printf("Track #%u: %s\n", i, track->psz_description);// 这里可以获取到每一个轨道的信息,比如轨道类型 track->i_type// 可能是 libvlc_track_video, libvlc_track_audio 或者 libvlc_track_text (字幕)if (track->i_type == libvlc_track_video) {// 处理视频轨道信息qDebug("width = %d",track->video->i_width);qDebug("height = %d", track->video->i_height);qDebug("rate_num = %d", track->video->i_frame_rate_num);qDebug("rate_den = %d", track->video->i_frame_rate_den);}else if (track->i_type == libvlc_track_audio) {// 处理音频轨道信息qDebug("channels = %d", track->audio->i_channels);qDebug("rate = %d", track->audio->i_rate);}else if (track->i_type == libvlc_track_text) {// 处理字幕轨道信息}}//获取事件管理器libvlc_event_manager_t *em = libvlc_media_player_event_manager(vlc_mediaPlayer);// 注册事件监听器libvlc_event_attach(em, libvlc_MediaPlayerTimeChanged, vlcEvents, this);libvlc_event_attach(em, libvlc_MediaPlayerEndReached, vlcEvents, this);libvlc_event_attach(em, libvlc_MediaPlayerStopped, vlcEvents, this);libvlc_event_attach(em, libvlc_MediaPlayerPlaying, vlcEvents, this);libvlc_event_attach(em, libvlc_MediaPlayerPaused, vlcEvents, this);libvlc_media_player_set_hwnd(vlc_mediaPlayer, (void *)ui.widgetShow->winId());QTimer::singleShot(1000, this, &showWidget::slotPlay);}void showWidget::slotPlay()
{if (vlc_mediaPlayer){libvlc_media_player_play(vlc_mediaPlayer);m_defalutScale = libvlc_video_get_scale(vlc_mediaPlayer);}}void showWidget::slotPause()
{if (vlc_mediaPlayer)libvlc_media_player_pause(vlc_mediaPlayer);
}void showWidget::slotStop()
{if (vlc_mediaPlayer)libvlc_media_player_stop(vlc_mediaPlayer);
}void showWidget::slotValueChanged(int value)
{if (vlc_mediaPlayer)libvlc_audio_set_volume(vlc_mediaPlayer, value);
}void showWidget::slotCurrentIndexChanged(int index)
{if (vlc_mediaPlayer)libvlc_media_player_set_rate(vlc_mediaPlayer, m_lstRate[index]);
}void showWidget::slotActionTriggered(QAction *action)
{if (!vlc_mediaPlayer)return;if (action == m_default)libvlc_video_set_aspect_ratio(vlc_mediaPlayer,m_defalutRate);else if(action == m_16_9)libvlc_video_set_aspect_ratio(vlc_mediaPlayer, "16:9");else if (action == m_4_3)libvlc_video_set_aspect_ratio(vlc_mediaPlayer, "4:3");else if (action == m_1_1)libvlc_video_set_aspect_ratio(vlc_mediaPlayer, "1:1");else if (action == m_16_10)libvlc_video_set_aspect_ratio(vlc_mediaPlayer, "16:10");else if (action == m_2_21_1)libvlc_video_set_aspect_ratio(vlc_mediaPlayer, "221:100");else if (action == m_2_35_1)libvlc_video_set_aspect_ratio(vlc_mediaPlayer, "235:100");else if (action == m_2_38_1)libvlc_video_set_aspect_ratio(vlc_mediaPlayer, "238:100");else if (action == m_5_4)libvlc_video_set_aspect_ratio(vlc_mediaPlayer, "5:4");action->setIcon(QIcon(":/image/images/point.png"));m_preAspectRatio->setIcon(QIcon());m_preAspectRatio = action;
}void showWidget::slotCropActionTriggered(QAction *action)
{if (!vlc_mediaPlayer)return;if (action == m__cropDefault)libvlc_video_set_crop_geometry(vlc_mediaPlayer, m_defalutCrop);else if (action == m__crop16_10)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "16:10");else if (action == m__crop16_9)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "16:9");else if (action == m__crop4_3)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "4:3");else if (action == m__crop1_85_1)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "185:100");else if (action == m__crop2_21_1)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "221:100");else if (action == m__crop2_35_1)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "235:100");else if (action == m__crop2_39_1)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "239:100");else if (action == m__crop5_3)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "5:3");else if (action == m__crop5_4)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "5:4");else if (action == m__crop1_1)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "1:1");action->setIcon(QIcon(":/image/images/point.png"));m_preCrop->setIcon(QIcon());m_preCrop = action;
}void showWidget::slotScaleActionTriggered(QAction *action)
{if (!vlc_mediaPlayer)return;if (action == m_scale1_4)libvlc_video_set_scale(vlc_mediaPlayer, 0.25);else if (action == m_scale1_2)libvlc_video_set_scale(vlc_mediaPlayer, 0.5);else if (action == m_scale1_1)libvlc_video_set_scale(vlc_mediaPlayer, 1);else if (action == m_scale2_1)libvlc_video_set_scale(vlc_mediaPlayer, 2);action->setIcon(QIcon(":/image/images/point.png"));m_preScale->setIcon(QIcon());m_preScale = action;
}void showWidget::slotSnap()
{if (vlc_mediaPlayer){QString path = "./snap.png";libvlc_video_take_snapshot(vlc_mediaPlayer, 0, path.toUtf8().data(), 0, 0);}
}//事件回调
void showWidget::vlcEvents(const libvlc_event_t *ev, void *param)
{showWidget *w = (showWidget*)param;//处理不同的事件switch (ev->type) {case libvlc_MediaPlayerTimeChanged:{//qDebug() << "VLC媒体播放器时间已更改";qint64 len = libvlc_media_player_get_time(w->vlc_mediaPlayer);libvlc_time_t lenSec = len / 1000;libvlc_time_t totalLen = libvlc_media_player_get_length(w->vlc_mediaPlayer);libvlc_time_t totalLenSec = totalLen / 1000;int thh, tmm, tss;thh = lenSec / 3600;tmm = (lenSec % 3600) / 60;tss = (lenSec % 60);QTime time(thh, tmm, tss);w->ui.lbCurTime->setText(time.toString("hh:mm:ss"));thh = totalLenSec / 3600;tmm = (totalLenSec % 3600) / 60;tss = (totalLenSec % 60);QTime TotalTime(thh, tmm, tss);w->ui.lbTotalTime->setText(TotalTime.toString("hh:mm:ss"));double pos = (double)lenSec / totalLenSec * 100;w->ui.horizontalSlider->setValue(pos);}break;case libvlc_MediaPlayerEndReached:qDebug() << "VLC播放完毕.";break;case libvlc_MediaPlayerStopped:qDebug() << "VLC停止播放";break;case libvlc_MediaPlayerPlaying:qDebug() << "VLC开始播放";break;case libvlc_MediaPlayerPaused:qDebug() << "VLC暂停播放";break;}
}void showWidget::initMenu()
{//总菜单m_menu = new QMenu(this);m_video = m_menu->addAction("视频");//视频菜单m_videoMenu = new QMenu(this);m_scaleAction = m_videoMenu->addAction("缩放");m_aspectRatioAction = m_videoMenu->addAction("宽高比");m_cropAction = m_videoMenu->addAction("裁剪");m_snapAction = m_videoMenu->addAction("截图");connect(m_snapAction, &QAction::triggered, this, &showWidget::slotSnap);m_video->setMenu(m_videoMenu);//宽高比菜单m_aspectRatioMenu = new QMenu(this);m_aspectRatioAction->setMenu(m_aspectRatioMenu);//设置宽高比菜单m_default = m_aspectRatioMenu->addAction(QIcon(":/image/images/point.png"), "默认");m_16_9 = m_aspectRatioMenu->addAction("16:9");m_4_3 = m_aspectRatioMenu->addAction("4:3");m_1_1 = m_aspectRatioMenu->addAction("1:1");m_16_10 = m_aspectRatioMenu->addAction("16:10");m_2_21_1 = m_aspectRatioMenu->addAction("2.21:1");m_2_35_1 = m_aspectRatioMenu->addAction("2.35:1");m_2_38_1 = m_aspectRatioMenu->addAction("2.38:1");m_5_4 = m_aspectRatioMenu->addAction("5:4");m_preAspectRatio = m_default;m_group = new QActionGroup(this);m_group->addAction(m_default);m_group->addAction(m_16_9);m_group->addAction(m_4_3);m_group->addAction(m_1_1);m_group->addAction(m_16_10);m_group->addAction(m_2_21_1);m_group->addAction(m_2_35_1);m_group->addAction(m_2_38_1);m_group->addAction(m_5_4);connect(m_group, &QActionGroup::triggered, this, &showWidget::slotActionTriggered);//设置裁剪菜单m_cropMenu = new QMenu(this);m_cropAction->setMenu(m_cropMenu);m__cropDefault = m_cropMenu->addAction(QIcon(":/image/images/point.png"), "默认");m__crop16_10 = m_cropMenu->addAction("16:10");m__crop16_9 = m_cropMenu->addAction("16:9");m__crop4_3 = m_cropMenu->addAction("4:3");m__crop1_85_1 = m_cropMenu->addAction("1.85:1");m__crop2_21_1 = m_cropMenu->addAction("2.21:1");m__crop2_35_1 = m_cropMenu->addAction("2.35:1");m__crop2_39_1 = m_cropMenu->addAction("2.39:1");m__crop5_3 = m_cropMenu->addAction("5:3");m__crop5_4 = m_cropMenu->addAction("5:4");m__crop1_1 = m_cropMenu->addAction("1:1");m_preCrop = m__cropDefault;m_cropGroup = new QActionGroup(this);m_cropGroup->addAction(m__cropDefault);m_cropGroup->addAction(m__crop16_10);m_cropGroup->addAction(m__crop16_9);m_cropGroup->addAction(m__crop4_3);m_cropGroup->addAction(m__crop1_85_1);m_cropGroup->addAction(m__crop2_21_1);m_cropGroup->addAction(m__crop2_35_1);m_cropGroup->addAction(m__crop2_39_1);m_cropGroup->addAction(m__crop5_3);m_cropGroup->addAction(m__crop5_4);m_cropGroup->addAction(m__crop1_1);connect(m_cropGroup, &QActionGroup::triggered, this, &showWidget::slotCropActionTriggered);//设置缩放菜单m_scaleMenu = new QMenu(this);m_scaleAction->setMenu(m_scaleMenu);m_scale1_4 = m_scaleMenu->addAction("1:4 四分之一");m_scale1_2 = m_scaleMenu->addAction("1:2 二分之一");m_scale1_1 = m_scaleMenu->addAction(QIcon(":/image/images/point.png"),"1:1 原始");m_scale2_1 = m_scaleMenu->addAction("2:1 双倍");m_scaleGroup = new QActionGroup(this);m_scaleGroup->addAction(m_scale1_4);m_scaleGroup->addAction(m_scale1_2);m_scaleGroup->addAction(m_scale1_1);m_scaleGroup->addAction(m_scale2_1);m_preScale = m_scale1_1;connect(m_scaleGroup, &QActionGroup::triggered, this, &showWidget::slotScaleActionTriggered);
}
更多参考:
libVLC 事件机制-CSDN博客
libVLC windows开发环境搭建-CSDN博客
https://sunnnnnn666.blog.csdn.net/article/details/137023036
相关文章:
libVLC 视频抓图
Windows操作系统提供了多种便捷的截图方式,常见的有以下几种: 全屏截图:通过按下PrtSc键(Print Screen),可以截取整个屏幕的内容。截取的图像会保存在剪贴板中,可以通过CtrlV粘贴到图片编辑工具…...
Docker搭建LNMP环境实战(06):Docker及Docker-compose常用命令
Docker搭建LNMP环境实战(06):Docker及Docker-compose常用命令 此处列举了docker及docker-compose的常用命令,一方面可以做个了解,另一方面可以在需要的时候进行查阅。不一定要强行记忆,用多了就熟悉了。 1、…...
ClickHouse10-ClickHouse中Kafka表引擎
Kafka表引擎也是一种常见的表引擎,在很多大数据量的场景下,会从源通过Kafka将数据输送到ClickHouse,Kafka作为输送的方式,ClickHouse作为存储引擎与查询引擎,大数据量的数据可以得到快速的、高压缩的存储。 Kafka大家…...
Encoding类
Encoding System.Text.Encoding 是 C# 中用于处理字符编码和字符串与字节之间转换的类。它提供了各种静态方法和属性,**用于在不同字符编码之间进行转换,**以及将字符串转换为字节数组或反之。 在处理多语言文本、文件、网络通信以及其他字符数据的场景…...
标定系列——预备知识-OpenCV中实现Rodrigues变换的函数(二)
标定系列——预备知识-OpenCV中实现Rodrigues变换的函数(二) 说明记录 说明 简单介绍罗德里格斯变换以及OpenCV中的实现函数 记录...
2014年认证杯SPSSPRO杯数学建模C题(第一阶段)土地储备方案的风险评估全过程文档及程序
2014年认证杯SPSSPRO杯数学建模 C题 土地储备方案的风险评估 原题再现: 土地储备,是指市、县人民政府国土资源管理部门为实现调控土地市场、促进土地资源合理利用目标,依法取得土地,进行前期开发、储存以备供应土地的行为。土地…...
我的编程之路:从非计算机专业到Java开发工程师的成长之路 | 学习路线 | Java | 零基础 | 学习资源 | 自学
小伙伴们好,我是「 行走的程序喵」,感谢您阅读本文,欢迎三连~ 😻 【Java基础】专栏,Java基础知识全面详解:👉点击直达 🐱 【Mybatis框架】专栏,入门到基于XML的配置、以…...
Django Cookie和Session
Django Cookie和Session 【一】介绍 【1】起因 HTTP协议四大特性 基于请求响应模式:客户端发送请求,服务端返回响应基于TCP/IP之上:作用于应用层之上的协议无状态:HTTP协议本身不保存客户端信息短链接:1.0默认使用短…...
【算法刷题 | 二叉树 04】3.27(翻转二叉树、对称二叉树、完全二叉树的节点个数、平衡二叉树、完全二叉树的所有路径)
文章目录 6.翻转二叉树6.1问题6.2解法一:递归6.2.1递归思路(1)确定递归函数的参数和返回值(2)确定终止条件(3)确定单层递归的逻辑 6.2.2全部代码 6.3解法二:层序遍历 7.对称二叉树7.…...
【uniapp】uniapp实现免密登录
文章目录 一、概要二、整体架构流程三、技术名词解释四 、技术细节1.存取token有效期?2.使用setStorageSync而不使用setStorage?3.使用onLaunch而不使用全局路由? 一、概要 打开一个网页或小程序的时候,我们有时候会自动进入主页…...
2024-03-27 问AI: 介绍一下深度学习中的 Darknet
文心一言 在深度学习中,Darknet是一个开源的神经网络框架,由Joseph Redmon开发,主要用于实现深度学习算法。它以其高效的实现和速度受到广泛关注,并在许多计算机视觉竞赛中取得了优异的结果。 Darknet的特点包括: 轻…...
POJ3037 + HDU-6714
两道最短路好题 POJ3037 手玩一下 发现每一点的速度可以直接搞出来,就是pow(2,h[1][1]-h[i][j])*V 那么从这个点出发到达别的点的耗费的时间都是上面这个数的倒数,然后直接跑最短路就好了 #include<iostream> #include<vector> #include<…...
Ubuntu搭建环境Cmake-Libtorch-Torchvision-PCL-VTK-OpenCV
Ubuntu搭建环境Cmake-Libtorch-Torchvision-PCL-VTK-OpenCV 安装Cmake安装libtorch安装torchvision安装PCL安装VTK安装OpenCV设置环境变量 仅供本人记录查阅使用 安装Cmake Cmake下载地址 解压 进入目录会看到只有 bin doc man share三个文件夹,没有 bootstrap文…...
分享多种mfc100u.dll丢失的解决方法(一键修复DLL丢失的方法)
在使用电脑过程中,我们经常会遇到一些陌生的DLL文件,例如mfc100u.dll。这些DLL文件是动态链接库(Dynamic Link Libraries)的缩写,它们包含了可以被多个程序共享的代码和数据。今天,我们将深入探讨mfc100u.d…...
Redis是单线程还是多线程?(面试题)
1、Redis5及之前是单线程版本 2、Redis6开始引入多线程版本(实际上是 单线程多线程 版本) Redis6及之前版本(单线程) Redis5及之前的版本使用的是 单线程,也就是说只有一个 worker队列,所有的读写操作都要…...
动态菜单设计
需求: 登录不同用户 显示不同的菜单 思路:根据用户id 左关联表 查询出对应的菜单选项 查询SQL select distinct-- 菜单表 去除重复记录sys_menu.id,sys_menu.parentId, sys_menu.name from -- 权限表sys_menu-- 角色与权限表 菜单表id 角色菜…...
Haproxy负载均衡介绍即部署
haproxy的原理: 提供高可用、负载均衡以及基于TCP(四层)和HTTP(七层)应用的代理,支持虚拟主机,开源可靠的一款软件。 适用于哪些负载特别大的web站点,这些站点通常又需要回话保持和七…...
基于大语言模型的云故障根因分析|顶会EuroSys24论文
*马明华 微软主管研究员 2021年CCF国际AIOps挑战赛程序委员会主席(第四届) 2021年博士毕业于清华大学,2020年在佐治亚理工学院做访问学者。主要研究方向是智能运维(AIOps)、软件可靠性。近年来在ICSE、FSE、ATC、EuroS…...
Windows直接运行python程序
Windows直接运行python程序 一、新建bat脚本二、新建vbs脚本 一、新建bat脚本 新建bat批处理脚本,写入以下内容 echo off call conda activate pytorch python app.pyecho off:在此语句后所有运行的命令都不显示命令行本身,但是本身的指令是…...
经典应用丨光伏行业扫码追溯新标杆,海康机器人AI智能读码器!
去年,光伏发电行业持续高速发展,我国仅在前九个月累计装机521.08GW,同比增长达到45.3%,已成为第二大电源类型超过水电。根据《2023中国与全球光伏发展白皮书》预测,到2030年,中国能够实现国家规划的风电和光…...
CRMEB 让您的在线商城更智能:最新商品模块更新亮点一览!
为了让广大电商商家更好地管理商品、提升用户的购物体验和满意度,近日,CRMEB标准版商城系统再度发力,对商品模块进行了全面升级,新增一系列功能,期待帮助企业商家更好地管理商品,提升用户购物体验ÿ…...
iOS自动化测试环境搭建:Appium+Python真机与模拟器全链路通关指南
1. 为什么iOS自动化测试环境搭建总让人卡在第一步?“AppiumPython实现iOS自动化测试~环境搭建”——这个标题里藏着太多新手看不见的暗礁。我带过三届测试团队,每年都有至少7个人卡在“连不上真机”“Xcode报错找不到WebDriverAgent”“模拟器启动后白屏…...
jquery.inputmask插件介绍
目录 一、什么是 jQuery.inputmask? 主要应用场景 二、快速上手 1. 引入依赖文件 2. 基础用法 3. 掩码字符定义 三、高级功能 1. 自定义占位符 2. 完成回调 3. 扩展自定义字符 4. 重复掩码 5. 移除默认占位符 四、配合 Vue.js 使用 五、更多实用示例 …...
Java基础小知识
一、 计算机基础知识1.计算机硬件的分类:运算器 控制器 存储器 输入设备 输出设备二、cmd命令窗口的基本用法操着: 说明:盘符名称 : 盘符切换。E:回车,表示切换到E盘dir 查看当前路径下的内容cd 目录 进入单级目录。cd…...
Llama3-8B微调显存优化实战:在单张RTX 4090上如何用PEFT+TRL跑通SFT?
Llama3-8B微调显存优化实战:单卡RTX 4090的极限挑战 当Meta发布Llama3系列模型时,8B版本因其在消费级硬件上的潜在可行性迅速成为开发者社区的焦点。但将这样一个拥有80亿参数的模型塞进24GB显存的显卡,就像试图把一头大象装进冰箱——理论上…...
保姆级排查指南:PyTorch装完CUDA不认账?手把手教你搞定torch.cuda.is_available()返回False
保姆级排查指南:PyTorch装完CUDA不认账?手把手教你搞定torch.cuda.is_available()返回False 刚装好PyTorch准备大展拳脚,结果torch.cuda.is_available()无情地返回False?这种挫败感我太懂了。作为过来人,我整理了这份…...
CANN/pypto isfinite函数文档
pypto.isfinite 【免费下载链接】pypto PyPTO(发音: pai p-t-o):Parallel Tensor/Tile Operation编程范式。 项目地址: https://gitcode.com/cann/pypto 产品支持情况 产品是否支持Ascend 950PR/Ascend 950DT√Atlas A3 训练系列产品…...
Amphenol ICC线束MSPEC6P2A5010应用与替代分析
随着工业通信、车载网络以及高速数据互联的发展,越来越多设备开始采用高性能线束组件来保证数据稳定传输。在工业自动化与智能设备领域,Amphenol ICC推出的MSPE系列近年来关注度持续提升,其中MSPEC6P2A5010就是比较典型的一款工业级线束组件。…...
【RK3588-AI-004】RK3588 AI专属依赖环境预装(Python、OpenCV、基础编译工具)
📖 专栏介绍 本专栏为RK3588 端侧AI开发零基础实战教程,专为嵌入式AI入门、模型部署、视觉开发学习者打造。全程实操、无废话、避坑优化,从零搭建RK3588专属AI开发环境,手把手教学,新手也能轻松上手。 ✅ 硬件适配&am…...
纤维增强复合材料多轴3D打印的神经网络协同优化
1. 纤维增强复合材料与多轴3D打印技术概述纤维增强复合材料(Fiber-Reinforced Composites)因其独特的力学性能组合——高强度、高刚度和低密度,已成为现代工程设计中不可或缺的材料选择。这类材料由高强度纤维(如碳纤维、玻璃纤维…...
