【Qt】图片绘制不清晰的问题
背景
实现一个图片浏览器,可以支持放大/缩小查看图片。主要组件如下:
// canvaswidget.h
#ifndef CANVASWIDGET_H
#define CANVASWIDGET_H#include <QWidget>class CanvasWidget : public QWidget
{Q_OBJECT
public:explicit CanvasWidget(QImage img, QWidget *parent = nullptr);void zoomIn();void zoomOut();signals:protected:QSize sizeHint();void paintEvent(QPaintEvent *event) override;void wheelEvent(QWheelEvent *event) override;private:qreal scale;QPixmap pixmap;
};#endif // CANVASWIDGET_H
// canvaswidget.cpp
#include "canvaswidget.h"
#include <QWheelEvent>
#include <QPainter>
#include <QPixmap>CanvasWidget::CanvasWidget(QImage img, QWidget *parent): QWidget{parent}, scale(1.0)
{pixmap = QPixmap::fromImage(img);
}void CanvasWidget::zoomIn() {scale = fmin(scale + 0.1, 10);update();
}void CanvasWidget::zoomOut() {scale = fmax(scale - 0.1, 0.1);update();
}void CanvasWidget::paintEvent(QPaintEvent *event) {if(!pixmap) {return QWidget::paintEvent(event);}QPainter p(this);p.setRenderHint(QPainter::Antialiasing);p.setRenderHint(QPainter::SmoothPixmapTransform);p.scale(scale, scale);p.drawPixmap(0,0,pixmap); // draw image
}void CanvasWidget::wheelEvent(QWheelEvent *event)
{if(event->modifiers() == Qt::ControlModifier) {QPointF delta = event->angleDelta();int v_delta = delta.y();if(v_delta > 0) {zoomIn();} else {zoomOut();}update();adjustSize();} else {QWidget::wheelEvent(event);}
}
QSize CanvasWidget::sizeHint()
{return QSize(800,800);
}
问题
在这种实现方式下,缩小图片时,图片会变得非常模糊,有非常明显的锯齿问题。
如下图所示,A是Windows自带图片查看器的效果,B是上述实现的效果。可以看出虽然B比A更大,但却更不清晰,有明显的锯齿。
尝试解决
为了解决这个不清晰的问题,尝试了很多种方案,方案及其实现方法如下:
不scale QPainter,而是在指定区域绘制Pixmap
p.drawPixmap(0,0,pixmap.size().width() * scale, pixmap.size().height * scale, pixmap);
使用QGraphicsView绘制图片
QPixmap pixmap("/path/to/image.png");QGraphicsScene scene;QGraphicsPixmapItem *item = new QGraphicsPixmapItem(pixmap);scene.addItem(item);QGraphicsView view;view.resize(800,600);view.setScene(&scene);// Optionally set view propertiesview.setRenderHint(QPainter::Antialiasing); // Improve rendering qualityview.setDragMode(QGraphicsView::ScrollHandDrag); // Enable draggingview.setAlignment(Qt::AlignCenter); // Center the imageview.fitInView(item, Qt::KeepAspectRatio); // Scale to fit the view// Show the viewview.show();
使用QWebEngineView绘制图片
QWebEngineView web_view;QString htmlContent = R"(<!DOCTYPE html><html><head><style>body { margin: 0; display: flex; justify-content: center; align-items: center; height: 100vh; }img { max-width: 100%; max-height: 100%; }</style></head><body><img src="/path/to/image.png" alt="Image Not Found"></body></html>)";web_view.setHtml(htmlContent, QUrl::fromLocalFile(QCoreApplication::applicationDirPath() + "/"));web_view.resize(800, 600);web_view.show();
将图片作为texture在QOpenGLWidget中绘制图片
#ifndef OPENGLIMAGE_H
#define OPENGLIMAGE_H#include <QOpenGLTexture>
#include <QOpenGLShaderProgram>
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QOpenGLBuffer>
#include <QOpenGLVertexArrayObject>
#include <memory>class OpenGLImage : public QOpenGLWidget, protected QOpenGLFunctions
{Q_OBJECT
public:explicit OpenGLImage(QWidget *parent = nullptr);~OpenGLImage();QSize minimumSizeHint() const override;QSize sizeHint() const override;void loadImage(QString& path);QMatrix4x4 getViewMatrix() const;QMatrix4x4 getModelMatrix() const;protected:void initializeGL() override;void paintGL() override;void resizeGL(int width, int height) override;void wheelEvent(QWheelEvent *event) override;void mouseMoveEvent(QMouseEvent *event) override;void mousePressEvent(QMouseEvent *event) override;void mouseReleaseEvent(QMouseEvent *event) override;void keyPressEvent(QKeyEvent *event) override;void keyReleaseEvent(QKeyEvent* event) override;private:void setupDefaultShaderProgram();void setupDefaultTransform();void drawImage();void moveImage(const QPointF& cursorPos);void rotateImage(const QPointF& cursorPos);std::unique_ptr<QOpenGLShaderProgram> shaderProgram;std::unique_ptr<QOpenGLTexture> texture;std::unique_ptr<QImage> image;QOpenGLBuffer vbo;QOpenGLVertexArrayObject vao;QOpenGLBuffer ebo;bool isTextureSync;QColor clearColor;float norm_h;QSize viewSize;QVector3D cameraPos;QVector3D imagePos;QVector3D imageAngle;float viewAngle;float focalLength;QPointF lastClickPos;bool isRotMode;
};#endif // OPENGLIMAGE_H
#include "glimageview.h"
#include <vector>
#include <QtMath>
#include <iostream>
#include <QResizeEvent>#define PROGRAM_VERTEX_ATTRIBUTE 0
#define PROGRAM_TEXCOORD_ATTRIBUTE 1#define DEFAULT_CAMERA_POS_X (0.0f)
#define DEFAULT_CAMERA_POS_Y (0.0f)
#define DEFAULT_CAMERA_POS_Z (-2.0f)#define CLIP_NEAR (0.01f)
#define CLIP_FAR (100.0f)#define MIN_FOCAL 1.0f
#define MAX_FOCAL 150.0fOpenGLImage::OpenGLImage(QWidget *parent): QOpenGLWidget(parent),shaderProgram(nullptr),texture(nullptr),image(nullptr),isTextureSync(false),clearColor(Qt::gray),norm_h(-1.0f),viewSize(640,640),ebo(QOpenGLBuffer::Type::IndexBuffer),viewAngle(45.0f),isRotMode(false)
{focalLength = 1/qTan(qDegreesToRadians(viewAngle/2.0f));
}OpenGLImage::~OpenGLImage()
{
}void OpenGLImage::initializeGL()
{initializeOpenGLFunctions();setupDefaultShaderProgram();
}void OpenGLImage::paintGL()
{glClearColor(clearColor.redF(), clearColor.greenF(), clearColor.blueF(), clearColor.alphaF());glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);drawImage();
}void OpenGLImage::resizeGL(int width, int height)
{viewSize = QSize(width, height);
}QSize OpenGLImage::minimumSizeHint() const
{int min_h = (int)(320.0f * norm_h);return QSize(320, min_h);
}QSize OpenGLImage::sizeHint() const
{return viewSize;
}void OpenGLImage::wheelEvent(QWheelEvent *event)
{QPoint numDegrees = event->angleDelta() / 8;float degree = (float)numDegrees.y() * -1.0f;degree /= 2.0f;if (viewAngle+degree > MIN_FOCAL && viewAngle+degree < MAX_FOCAL) {viewAngle += degree;focalLength = 1/qTan(qDegreesToRadians(viewAngle/2.0f));}event->accept();update();
}void OpenGLImage::drawImage() {if (image.get() == nullptr) return;glViewport(0, 0, viewSize.width(), viewSize.height());// qDebug() << viewSize.width() << ", " << viewSize.height() << "\n";// setup vertex array objectif (!vao.isCreated()){vao.create();}vao.bind();// setup vertex buffer objectstd::vector<GLfloat> coords;// bottom left;coords.push_back(-1.0f);coords.push_back(-1.0f * norm_h);coords.push_back(0.0f);// tex coordinatecoords.push_back(0.0f);coords.push_back(0.0f);// bottom rightcoords.push_back(1.0f);coords.push_back(-1.0f * norm_h);coords.push_back(0.0f);// tex coordinatecoords.push_back(1.0f);coords.push_back(0.0f);// top rightcoords.push_back(1.0f);coords.push_back(1.0f * norm_h);coords.push_back(0.0f);// tex coordinatecoords.push_back(1.0f);coords.push_back(1.0f);// top leftcoords.push_back(-1.0f);coords.push_back(1.0f * norm_h);coords.push_back(0.0f);// tex coordinatecoords.push_back(0.0f);coords.push_back(1.0f);if (!vbo.isCreated()){vbo.create();}vbo.bind();vbo.allocate(coords.data(), coords.size()*sizeof(GLfloat));// setup vertex element object// [bl, br, tr, tl]static const std::vector<GLuint> indices {0, 1, 2,2, 3, 0};if (!ebo.isCreated()){ebo.create();}ebo.bind();ebo.allocate(indices.data(), indices.size()*sizeof(GLuint));// associate vertex and buffershaderProgram->enableAttributeArray(PROGRAM_VERTEX_ATTRIBUTE);shaderProgram->enableAttributeArray(PROGRAM_TEXCOORD_ATTRIBUTE);shaderProgram->setAttributeBuffer(PROGRAM_VERTEX_ATTRIBUTE, GL_FLOAT, 0, 3, 5 * sizeof(GLfloat));shaderProgram->setAttributeBuffer(PROGRAM_TEXCOORD_ATTRIBUTE, GL_FLOAT, 3 * sizeof(GLfloat), 2, 5 * sizeof(GLfloat));// assign transform matricesQMatrix4x4 projection; // projection matrxi must update everytime!float ratio = ((float)viewSize.width())/((float)viewSize.height());projection.perspective(viewAngle, ratio, CLIP_NEAR, CLIP_FAR);QMatrix4x4 model = getModelMatrix();model.rotate(imageAngle.x(), 0.0f, 1.0f, 0.0f);model.rotate(imageAngle.y()*-1.0f, 1.0f, 0.0f, 0.0f);shaderProgram->setUniformValue("model", model);QMatrix4x4 viewMat = getViewMatrix();shaderProgram->setUniformValue("view", viewMat);shaderProgram->setUniformValue("projection", projection);// setup textureif (texture.get() == nullptr || !isTextureSync) {QImage& img = *image.get();texture = std::unique_ptr<QOpenGLTexture>(new QOpenGLTexture(img));isTextureSync = true;}texture->bind();glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0 );
}void OpenGLImage::setupDefaultShaderProgram()
{QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this);const char *vsrc ="attribute highp vec3 vertex;\n""uniform mediump mat4 model;\n""uniform mediump mat4 view;\n""uniform mediump mat4 projection;\n""\n""attribute mediump vec2 texCoord;\n""varying mediump vec2 texc;\n""void main(void)\n""{\n"" gl_Position = projection * view * model * vec4(vertex, 1.0f);\n"" texc = texCoord;\n""}\n";vshader->compileSourceCode(vsrc);QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this);const char *fsrc ="uniform sampler2D texture;\n""varying mediump vec2 texc;\n""void main(void)\n""{\n"" gl_FragColor = texture2D(texture, texc);\n""}\n";fshader->compileSourceCode(fsrc);shaderProgram = std::unique_ptr<QOpenGLShaderProgram>(new QOpenGLShaderProgram(this));shaderProgram->addShader(vshader);shaderProgram->addShader(fshader);// assign locations of vertex and texture coordinatesshaderProgram->bindAttributeLocation("vertex", PROGRAM_VERTEX_ATTRIBUTE);shaderProgram->bindAttributeLocation("texCoord", PROGRAM_TEXCOORD_ATTRIBUTE);shaderProgram->link();shaderProgram->bind();shaderProgram->setUniformValue("texture", 0);
}void OpenGLImage::setupDefaultTransform() {cameraPos = QVector3D(DEFAULT_CAMERA_POS_X, DEFAULT_CAMERA_POS_Y, DEFAULT_CAMERA_POS_Z);imagePos = QVector3D();imageAngle = QVector3D();
}void OpenGLImage::loadImage(QString& path) {QImage* p = new QImage(QImage(path).mirrored());image = std::unique_ptr<QImage>(p);isTextureSync = false;norm_h = (float)((float)image->height()/(float)image->width());int h = (int)((float)viewSize.width()*norm_h);viewSize = QSize(viewSize.width(), h);resize(viewSize);setupDefaultTransform();
}QMatrix4x4 OpenGLImage::getViewMatrix() const {QVector3D up(0.0f, 1.0f, 0.0f);QMatrix4x4 ret;ret.translate(cameraPos);QVector3D center(cameraPos.x(), cameraPos.y(), imagePos.z());ret.lookAt(QVector3D(), center, up);return ret;
}QMatrix4x4 OpenGLImage::getModelMatrix() const {QMatrix4x4 ret;ret.translate(imagePos);return ret;
}void OpenGLImage::mousePressEvent(QMouseEvent *event) {lastClickPos = event->localPos();qDebug() << lastClickPos;
}// movement is weird somehow...
void OpenGLImage::mouseMoveEvent(QMouseEvent *event) {if (isRotMode) {rotateImage(event->localPos());} else {moveImage(event->localPos());}lastClickPos = event->pos();event->accept();update();
}void OpenGLImage::moveImage(const QPointF &cursorPos) {QPointF delta = cursorPos-lastClickPos;float factor = qAbs(imagePos.z()-cameraPos.z()) / focalLength;factor /= (qMax(viewSize.width(), viewSize.height()));factor *= 3.5f;qDebug() << "dx=" << delta.x();qDebug() << "dy=" << delta.y();qDebug() << "L=" << (imagePos.z()-cameraPos.z());qDebug() << "focalLength=" << focalLength;qDebug() << "factor" << factor;delta *= factor;imagePos += QVector3D(delta.x(), -1.0f*delta.y(), 0.0f);
}void OpenGLImage::rotateImage(const QPointF &cursorPos) {QPointF delta = cursorPos-lastClickPos;delta.setX(delta.x() / (qreal)viewSize.width());delta.setX(delta.x() * 180.0f);delta.setY(delta.y() / (qreal)viewSize.height());delta.setY(delta.y() * -180.0f);qDebug() << delta;imageAngle += QVector3D(delta.x(), delta.y(), 0.0f);
}void OpenGLImage::mouseReleaseEvent(QMouseEvent *event) {
}void OpenGLImage::keyPressEvent(QKeyEvent *event) {if (event->key() == Qt::Key_Control) {qDebug() << "ctrl is pressed";isRotMode = true;} else {// call base class method as event is not handled.QOpenGLWidget::keyPressEvent(event);}
}void OpenGLImage::keyReleaseEvent(QKeyEvent *event) {if (event->key() == Qt::Key_Control) {qDebug() << "ctrl is released";isRotMode = false;} else {// call base class method as event is not handled.QOpenGLWidget::keyReleaseEvent(event);}
}
如下图所示,不同方案的效果略有不同,但所有方案都会出现缩小后图片变模糊的问题:
问题所在
最终在网友们的帮助下,发现了问题所在:这些实现方法在修改图片大小时都会对图片进行压缩。
比如void QPainter::drawPixmap(const QRectF &target, const QPixmap &pixmap, const QRectF &source)
,在指定矩形区域内绘制图片,如果指定的矩形区域比图片本身尺寸小,绘制过程中就会对图片进行压缩,导致图片变得模糊。
如果想要将图片变小的同时,保持图片的清晰度,应该直接使用QPixmap
的scaled函数:
p.drawPixmap(0,0,pixmap.scaled(pixmap.size() * scale, Qt::KeepAspectRatio, Qt::SmoothTransformation));
效果如下,左边是新的实现方法的效果,右边是Windows自带的图片查看软件的效果:
其实我一开始的实现方法不算错,甚至是官方建议的,在QPixmap的文档中提到:
In some cases it can be more beneficial to draw the pixmap to a painter with a scale set rather than scaling the pixmap. This is the case when the painter is for instance based on OpenGL or when the scale factor changes rapidly.
图片查看器其实就会频繁改变scale
,按照建议就是应该采用修改QPainter的scale
的方法,但这种方法确实会导致图片清晰度变低,出现模糊的问题。
相关文章:
【Qt】图片绘制不清晰的问题
背景 实现一个图片浏览器,可以支持放大/缩小查看图片。主要组件如下: // canvaswidget.h #ifndef CANVASWIDGET_H #define CANVASWIDGET_H#include <QWidget>class CanvasWidget : public QWidget {Q_OBJECT public:explicit CanvasWidget(QImag…...
2008年IMO几何预选题第3题
设有两个圆凸内接四边形 A B Q D ABQD ABQD 和 B P Q C BPQC BPQC, 在线段 P Q PQ PQ 上存在一点 E E E, 使得, ∠ E A P ∠ E D Q \angle EAP\angle EDQ ∠EAP∠EDQ, ∠ E B P ∠ E C Q \angle EBP\angle ECQ ∠EBP∠ECQ. 求证: A A A, B B B, C C C, D D D 四点共…...
NAT拓展
NAT ALG(NAT应用级网) 为某些应用层协议,因为其报文内容可能携带IP相关信息,而普通NAT转化无法将这些IP转化,从而导致协议无法正常运行 例如FTP,DHCP,RSTP,ICMP,IPSEC…...
Flink四大基石之State
State state 可以理解为-- 历史计算结果 有状态计算和无状态计算 无状态计算: 不需要考虑历史数据, 相同的输入,得到相同的输出!如:map, 将每个单词记为1, 进来一个hello, 得到(hello,1),再进来一个hello,得到的还是(hello,1) 有状态计算: 需要考虑历史数据, 相同的输入,可…...
Spacy小笔记:zh_core_web_trf、zh_core_web_lg、zh_core_web_md 和 zh_core_web_sm区别
Spacy小笔记 最近频繁用到spacy,就小记一下。 2024.11.29 zh_core_web_trf、zh_core_web_lg、zh_core_web_md 和 zh_core_web_sm区别 首先,它们都是预训练的中文模型: zh_core_web_trf:395M 架构: 基于 Transformer 架构(bert…...
第六届智能控制、测量与信号处理国际学术会议 (ICMSP 2024)
重要信息 2024年11月29日-12月1日 中国陕西西安石油大学雁塔校区 大会官网:www.icmsp.net 大会简介 第六届智能控制、测量与信号处理国际学术会议(ICMSP 2024)由西安石油大学、中海油田服务股份有限公司、浙江水利水电学院与中国石油装备…...
docker服务容器化
docker服务容器化 1 引言2 多个容器间网络联通2.1 单独创建关联2.2 创建时关联 3 服务搭建3.1 镜像清单3.2 容器创建 4 联合实战4.2 flink_sql之kafka到starrocks4.2 flink_sql之mysql到starrocks 5 文献借鉴 1 引言 利用docker可以很效率地搭建服务,本文在win1…...
【QT】控件8
1.QDial 通过调节旋钮位置来控制窗口的不透明度: void Widget::on_dial_valueChanged(int value) {qDebug()<<value;this->setWindowOpacity((double)value/100); }效果演示: 2.Date/Time Edit 计算两个日期的差值 ui界面设计 计算按钮按下…...
漫谈推理谬误——错误因果
相关文章 漫谈推理谬误——错误假设-CSDN博客文章浏览阅读736次,点赞22次,收藏3次。在日常生活中,我们会面临各种逻辑推理,有些看起来一目了然,有些非常的科学严谨,但也有很多似是而非,隐藏了陷…...
【数据结构】队列实现剖析:掌握队列的底层实现
在计算机科学中,**队列(Queue)**是一种常见的数据结构,它遵循先进先出(FIFO,First In First Out)的原则。队列的应用非常广泛,例如任务调度、资源管理、进程通信等。本篇文章旨在为计…...
【C++】IO库(二):文件输入输出
8.2 文件输入输出 头文件 fstream 定义了三个类型来之支持文件IO,分别是: ifstream:从一个给定文件读取数据;ofstream:向一个给定文件写入数据;fstream:读写给定文件。 在 C 当中,…...
105.【C语言】数据结构之二叉树求总节点和第K层节点的个数
目录 1.求二叉树总的节点的个数 1.容易想到的方法 代码 缺陷 思考:能否在TreeSize函数内定义静态变量解决size的问题呢? 其他写法 运行结果 2.最好的方法:分而治之 代码 运行结果 2.求二叉树第K层节点的个数 错误代码 运行结果 修正 运行结果 其他写法 1.求二…...
力扣637. 二叉树的层平均值
给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5 以内的答案可以被接受。 提示: 树中节点数量在 [1, 104] 范围内-231 < Node.val < 231 - 1 代码: /*** Definition for a binary tree node.* stru…...
【前端】Next.js 服务器端渲染(SSR)与客户端渲染(CSR)的最佳实践
关于Next.js 服务器端渲染(SSR)与客户端渲染(CSR)的实践内容方面,我们按下面几点进行阐述。 1. 原理 服务器端渲染 (SSR): 在服务器上生成完整的HTML页面,然后发送给客户端。这使得用户在首次访问时能够…...
路径规划之启发式算法之一:A-Star(A*)算法
A*算法是一种启发式搜索算法,常用于解决路径规划问题。 一、A*算法的定义与原理 A*算法是一种用于在图形或网格中查找最短路径的算法。它在搜索过程中综合考虑了每个节点的实际距离(g值)和预估距离(h值),以…...
Android复习代码1-4章
public class RudioButton extends AppCompatActivity {Overrideprotected void onCreate(Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_rudio_button);// 找到RadioGroup和TextView的实例RadioGroup radioGrou…...
【问题】webdriver.Chrome()设置参数executable_path报不存在
场景1: 标红报错unresolved reference executable_path 场景2: 执行报错TypeError: __init__() got an unexpected keyword argument executable_path 原因: 上述两种场景是因为selenium4开始不再支持某些初始化参数。比如executable_path 解决: 方案…...
win10系统安装docker-desktop
1、开启Hyper-v ———————————————— Hyper-V 是微软提供的一种虚拟化技术,它允许你在同一台物理计算机上运行多个独立的操作系统实例。这种技术主要用于开发、测试、以及服务器虚拟化等领域。 —————————————————————— &#…...
小程序-基于java+SpringBoot+Vue的乡村研学旅行平台设计与实现
项目运行 1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA; 3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可 4.硬件环境:…...
组件A底部栏(position: fixed )事件使用$emit更新内容失败bug解决
今天遇到一个很离奇的bug,记录一下 问题:在组件内底部栏使用$emit触发按钮事件但打印出来的值是初始化的值,更新的值被重置导致更新失败 原因:组件内底部使用了 position: fixed; 固定, 导致组件内插槽 this 与 保存按…...
数据结构——排序第三幕(深究快排(非递归实现)、快排的优化、内省排序,排序总结)超详细!!!!
文章目录 前言一、非递归实现快排二、快排的优化版本三、内省排序四、排序算法复杂度以及稳定性的分析总结 前言 继上一篇博客基于递归的方式学习了快速排序和归并排序 今天我们来深究快速排序,使用栈的数据结构非递归实现快排,优化快排(三路…...
C++的类功能整合
1. 类的基本概念 类是面向对象编程的核心,它封装了数据和操作数据的函数。 #include <iostream> using namespace std;class MyClass { public:int publicData;void publicFunction() {cout << "Public function" << endl;}private:i…...
《String类》
目录 一、定义与概述 二、创建字符串对象 2.1 直接赋值 2.2 使用构造函数 三、字符串的不可变性 四、常用方法 4.1 String对象的比较 4.1.1 比较是否引用同一个对象 4.1.2 boolean equals(Object anObject)方法:按照字典序比较 4.1.3 int compareTo(Strin…...
【docker】docker的起源与容器的由来、docker容器的隔离机制
Docker 的起源与容器的由来 1. 虚拟机的局限:容器的需求萌芽 在 Docker 出现之前,开发和部署软件主要依赖虚拟机(VMs): 虚拟机通过模拟硬件运行操作系统,每个应用程序可以运行在自己的独立环境中。虽然虚…...
Window 安装 Nginx
参考链接 Windows 环境nginx安装使用及目录结构详解_windows 安装nginx-CSDN博客 Nginx 安装及配置教程(Windows)【安装】_nginx下载安装-CSDN博客 安装 1)下载 nginx: download 2)解压 3)启动 3.1)方…...
replace (regexp|substr, newSubstr|function)替换字符串中的指定部分
replace 方法用于替换字符串中的指定部分。它可以接受一个子字符串或正则表达式作为第一个参数,第二个参数是替换的内容。 用法示例 基本替换 let str "Hello, world!"; let newStr str.replace("world", "everyone"); console.lo…...
【ROS2】Ubuntu22.04安装ROS humble
一. ROS简介 1.1 什么是ROS ROS 是一个适用于机器人的开源的元操作系统。它提供了操作系统应有的服务,包括硬件抽象,底层设备控制,常用函数的实现,进程间消息传递,以及包管理。ROS的核心思想就是将机器人的软件功能做…...
cesium 3Dtiles变量
原本有一个变亮的属性luminanceAtZenith,但是新版本的cesium没有这个属性了。于是 let lightColor 3.0result._customShader new this.ffCesium.Cesium.CustomShader({fragmentShaderText:void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial mate…...
配置泛微e9后端开发环境
配置泛微e9的后端开发环境 1.安装jdk1.8(请自行安装并设置环境变量) 2.将服务器上的WEARVER文件夹拷贝到开发环境下(其中要包含ecology和Resin目录) 3.通过idea创建一个基础Java项目,将jdk设置为1.8 4.添加依赖,需要将3个文件夹的所有jar包添加到项目中…...
【Stable Diffusion】安装教程
目录 一、python 安装教程 二、windows cuda安装教程 三、Stable Diffusion下载 四、Stable Diffusion部署(重点) 一、python 安装教程 (1)第一步下载 打开python下载页面,找到python3.10.9,点击右边…...
山东爱易网站建设工作室/高端企业网站模板
1. 项目背景 1.1. 项目简介 公司有一个正在运营中的电商网站,名称叫做【京京购】。这是一个B2B2C的电商平台,类似京东。 现在我们想了解一下该电商网站的各种用户行为(访问行为、购物行为、点击行为等),统计出PV、U…...
政府网站建设设计方案/seo岗位培训
...if (!$dateTimeString) { $dateTimeString time(); } $numeric ; $add_space false; for($i0;$iMySQL支持所有标准SQL数值数据类型。这些类型包括严格数值数据类型(INTEGER、SMALLINT、DECIMAL和NUMERIC),以及近似数值数据类型(FLOAT、REAL和DOUBLE PRECISION…...
高端html5网站建设织梦模板/seo监控系统
一个简单的OpenMP例子首先启动VisualStudio 2010,新建一个C的控制台应用程序,如下图所示:然后在项目解决方案资源管理器上选择项目名称,点击右键,选择“属性”,如下图所示:然后在属性页上左侧选…...
企业网站开发模板/镇江百度公司
1.查看当前Python版本 # python -V Python 2.6.6 2.下载Python2.7.6源码 # wget http://python.org/ftp/python/2.7.6/Python-2.7.6.tgz 为防止网络不稳定,我都是下下来,再传进去,xftp传就可以了3.解压源代码包 # tar xvf Py…...
做网站赚取广告费/seo查询 站长之家
前言很高兴现在接手的项目让我接触到了Python Graphql,百度上对其介绍相对较少也不够全面,几乎没有完整的中文文档,所以这边也借此机会学习一下Graphql。什么是Graphql呢?Graphql是一个API查询语言,其数据由服务器上的…...
wordpress做在线编辑图片/淘宝优化
CentOS7创建用户命令 参数: -u 指定UID添加用户 -g 指定用户属于哪个组(GID) -M 不生成用户目录 -s 指定解释器 不添加任何参数,创建 kali 用户 不加参数时,创建用户默认创建一个用户目录以及用户和组同名,且UID和GID相同 useradd kali用 id和 ll 命令查看一下,是否成功创…...