Compare commits

...

59 Commits

Author SHA1 Message Date
flykhan a0ea598880 其他未完成 2023-08-14 17:21:53 +08:00
flykhan 3fb8491555 day13 homework: 百度AI测试: 身份证-银行卡-驾驶证识别 2023-06-30 09:35:41 +08:00
flykhan f7ba76c56f day13 coding: 百度AI测试: 车牌识别 2023-06-30 09:34:50 +08:00
flykhan 6f894cb9b1 day12 coding Qt作业:猜拳(改bug,优化代码) 2023-06-29 10:12:24 +08:00
flykhan de36ac8b3c day12 coding Qt案例: 上课代码 2023-06-28 23:02:58 +08:00
flykhan fc4b1e799b 删除错误文件 2023-06-28 22:59:31 +08:00
flykhan 3d5f265596 day12 coding Qt案例练习 2023-06-28 22:57:56 +08:00
flykhan 554a5f12d0 day12 coding Qt作业: 猜拳游戏 2023-06-28 22:57:03 +08:00
flykhan f36cc5ce97 day11 coding Qt案例: 切换AB界面 2023-06-27 22:44:31 +08:00
flykhan 5bcb4c519d day11 coding Qt案例: 餐馆点餐 2023-06-27 20:45:52 +08:00
flykhan 1c2e268a52 day11 coding Qt案例: 热了与冷饮 2023-06-27 15:43:16 +08:00
flykhan e7d3739038 day9 homework 2023-06-26 20:46:20 +08:00
flykhan 98bb2cf0f1 初始qt 2023-06-26 19:00:04 +08:00
flykhan 4295013896 修订 2023-06-26 14:46:00 +08:00
flykhan 4c474d31c5 添加 gitignore 规则: qt 2023-06-26 12:42:12 +08:00
flykhan 1424dc8874 day9 coding 2023-06-26 08:34:05 +08:00
flykhan ce1d2ae68f 定义函数, 实现字符串中某个字符的查找, 并返回字符的下标或 -1 2023-06-25 16:59:08 +08:00
flykhan 782d75d3b1 定义函数, 实现字符串的反转并输出 2023-06-25 16:03:32 +08:00
flykhan f3750b2851 修正: 斐波那契 2023-06-24 10:43:50 +08:00
flykhan 7b07eb048f 斐波那契数列 2023-06-24 10:38:43 +08:00
flykhan eae410f777 输出一个数的阶乘 2023-06-24 10:23:45 +08:00
flykhan 5434ce3192 输出一个数的所有因数 2023-06-24 10:19:24 +08:00
flykhan 6859943be2 day8 homework 2023-06-24 10:01:33 +08:00
flykhan af5944bc12 day8 coding 2023-06-23 17:31:07 +08:00
flykhan 1dfa86844c day7 coding 2023-06-21 14:30:56 +08:00
flykhan 690d495f38 day7 homework 2023-06-21 11:31:26 +08:00
flykhan 300c745459 使用位运算符实现以下条件:交换两个数的值。 2023-06-20 08:52:14 +08:00
flykhan 485b93466b 使用逻辑运算符实现以下条件:输入三个数,输出其中最小的数。 2023-06-20 08:52:06 +08:00
flykhan a7d39aa736 使用逻辑运算符实现以下条件:输入三个数,输出其中最大的数。 2023-06-20 08:51:57 +08:00
flykhan 84fb470ed7 使用位运算符实现以下条件:判断一个数是否为偶数。 2023-06-20 08:51:54 +08:00
flykhan 8401248063 输入两个数,如果它们都是正数,输出它们的和;如果它们都是负数,输出它们的积;否则输出它们的差。 2023-06-20 08:50:11 +08:00
flykhan ffb080d49f 将一个数的第 n 位(从右往左数)翻转,即如果原来是 0,变为 1;如果原来是 1,变为 0。 2023-06-20 08:49:55 +08:00
flykhan acabbbf714 使用位运算符实现以下条件:将一个数的第 n 位(从右往左数)设为 0。 2023-06-20 08:49:38 +08:00
flykhan 0808f742c6 使用位运算符实现以下条件:将一个数的第 n 位(从右往左数)设为 1。 2023-06-20 08:49:27 +08:00
flykhan f04064a186 逻辑运算题1 2023-06-20 08:49:19 +08:00
flykhan 13211e1919 逻辑运算题1 2023-06-20 08:48:57 +08:00
flykhan 1acf92d7ab 使用位运算符实现以下条件:判断一个数是否为偶 2023-06-20 08:46:15 +08:00
flykhan 3b1774ccab 三目运算符 2023-06-19 16:55:34 +08:00
flykhan a53db5f59b 位运算的综合应用 2023-06-19 16:20:48 +08:00
flykhan 49565a55df 逻辑右移 || 算术右移 2023-06-19 15:54:34 +08:00
flykhan 1ab9831597 位运算左移 2023-06-19 15:41:30 +08:00
flykhan 6f86054fb6 添加取反说明技巧 2023-06-19 15:25:02 +08:00
flykhan 428eaec33c 按位取反 2023-06-19 15:23:37 +08:00
flykhan ce8fa14892 位与&&位或 2023-06-19 15:14:11 +08:00
flykhan 1a98dde7d5 逻辑运算符 2023-06-19 15:08:08 +08:00
flykhan b1523467f8 位运算:左移 2023-06-19 14:09:46 +08:00
flykhan 30bd068d05 按位取反 2023-06-19 11:45:43 +08:00
flykhan 7459ef21df 测试抽奖题目(随机数生成) 2023-06-16 17:44:32 +08:00
flykhan c92bf394ee 生成a-z之间的随机字符 2023-06-16 17:42:16 +08:00
flykhan 4adc5f4057 更正gitignore 2023-06-16 16:34:13 +08:00
flykhan 73c735a0e4 测试goto语句 2023-06-16 16:34:00 +08:00
flykhan e9a0cb266e 无符号数 2023-06-16 16:33:51 +08:00
flykhan e5373892a1 源码反码补码 2023-06-16 16:33:40 +08:00
flykhan d545e83aa5 进制转换 2023-06-16 16:33:32 +08:00
flykhan 1f93e821ed 测试负数的二进制表示:补码方式存储 2023-06-16 16:33:04 +08:00
flykhan 896ab0ca76 sizeof 2023-06-16 16:32:52 +08:00
flykhan c9353fa3fe 测试一个整数能否被3整除 2023-06-16 16:32:44 +08:00
flykhan 2ffc4d5eaa 测试随机数 2023-06-16 16:32:34 +08:00
flykhan 74f9c23f9e 打印九九乘法表 2023-06-16 16:01:52 +08:00
214 changed files with 13806 additions and 0 deletions
+563
View File
@@ -92,4 +92,567 @@ dkms.conf
*.s
*.o
*.swp
.vscode
*/test
# ---> Qt
# C++ objects and libs
*.slo
*.lo
*.o
*.a
*.la
*.lai
*.so
*.so.*
*.dll
*.dylib
# Qt-es
object_script.*.Release
object_script.*.Debug
*_plugin_import.cpp
/.qmake.cache
.qmake.cache
/.qmake.stash
.qmake.stash
*.pro.user
*.pro.user.*
*.qbs.user
*.qbs.user.*
*.moc
moc_*.cpp
moc_*.h
qrc_*.cpp
ui_*.h
*.qmlc
*.jsc
#Makefile*
*build-*
*.qm
*.prl
# Qt unit tests
target_wrapper.*
# QtCreator
*.autosave
# QtCreator Qml
*.qmlproject.user
*.qmlproject.user.*
# QtCreator CMake
CMakeLists.txt.user*
# QtCreator 4.8< compilation database
compile_commands.json
# QtCreator local machine specific files for imported projects
*creator.user*
*_qmlcache.qrc
# ---> VisualStudio
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.tlog
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
*.vbp
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
*.dsw
*.dsp
# Visual Studio 6 technical files
*.ncb
*.aps
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# Visual Studio History (VSHistory) files
.vshistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
# VS Code files for those working on multiple tools
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
# Local History for Visual Studio Code
.history/
# Windows Installer files from build outputs
*.cab
*.msi
*.msix
*.msm
*.msp
# JetBrains Rider
*.sln.iml
# ---> VisualStudioCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
# Local History for Visual Studio Code
.history/
# Built Visual Studio Code Extensions
*.vsix
# ---> C
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
# ---> C++
# Prerequisites
*.d
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
.vscode
+17
View File
@@ -0,0 +1,17 @@
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
// 1. Qt 应用程序
QApplication a(argc, argv);
// 2. 应用程序中显示的主窗口
Widget w;
w.show();
// 3. 启动 Qt 程序, 监听窗口的相关事件
// 直到窗口关闭事件发生才退出
return a.exec(); // a.exec 的目的是保持程序活着
}
+28
View File
@@ -0,0 +1,28 @@
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
widget.cpp
HEADERS += \
widget.h
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
+41
View File
@@ -0,0 +1,41 @@
#include "widget.h"
#include <QApplication>
#include <QPushButton>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
this->setWindowTitle("我是第一个小窗口");
// this -> resize(200,300);
this->setFixedSize(QSize(480, 320));
// 创建一个按钮
// c++中创建类对象的两种方式:
// 1) 类名 对象 (构造函数的)
QPushButton *btn = new QPushButton("退出");
btn->resize(100, 50); // 设置控件的大小
btn->setParent(this); // 设置控件在哪一个窗口显示
btn->move(190, 135);
// connect(btn,&QPushButton::clicked,this,&QApplication::quit);
connect(btn, &QPushButton::clicked, this, &QWidget::close);
QPushButton *btn2 = new QPushButton("2");
btn2->resize(100, 50); // 设置控件的大小
btn2->setParent(this); // 设置控件在哪一个窗口显示
btn2->move(190 + 100, 135);
QPushButton *btn3 = new QPushButton("3");
btn3->resize(100, 50); // 设置控件的大小
btn3->setParent(this); // 设置控件在哪一个窗口显示
btn3->move(190 + 200, 135);
}
Widget::~Widget()
{
}
+14
View File
@@ -0,0 +1,14 @@
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
};
#endif // WIDGET_H
+11
View File
@@ -0,0 +1,11 @@
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
+28
View File
@@ -0,0 +1,28 @@
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
widget.cpp
HEADERS += \
widget.h
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
+56
View File
@@ -0,0 +1,56 @@
#include "widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
setWindowTitle("加法计数器");
setFixedSize(500,100);
QPushButton *sumBtn=new QPushButton("计算",this);
sumBtn->setFixedSize(100,50);
sumBtn->move(300,25);
le1 = new QLineEdit(this);
le2 = new QLineEdit(this);
le1->setFixedSize(100,50);
le2->setFixedSize(100,50);
le1->move(0,25);
le2->move(200,25);
lable1 = new QLabel(this);
lable1->setText("+");
lable1->setFixedSize(10,50);
lable1->move(145,25);
lable2 = new QLabel(this);
lable2->setText("计算结果");
lable2->setFixedSize(100,50);
lable2->move(400,25);
connect(sumBtn,&QPushButton::clicked,this,&Widget::sum);
// connect(sumBtn,&QPushButton::clicked,this,lable2->setText(QString::number(c)));
}
void Widget::sum(){
lable2->setText("点击");
QString n1 = le1->text();
QString n2 = le2->text();
qDebug() << n1 << " " << n2;
// 将文本转化为数值
int ret = n1.toInt()+n2.toInt();
QString str = QString::number(ret);
qDebug() << str;
lable2->setText(str);
}
Widget::~Widget()
{
}
+27
View File
@@ -0,0 +1,27 @@
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <iostream>
#include <QPushButton> // 按钮
#include <QLineEdit> // 文本输入框
#include <QLabel> // 文本标签
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
public slots:
// 自定义槽函数, 需要在源文件中去实现函数功能
void sum();
private:
QLineEdit *le1,*le2;
QLabel *lable1,*lable2;
};
#endif // WIDGET_H
+11
View File
@@ -0,0 +1,11 @@
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
+33
View File
@@ -0,0 +1,33 @@
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
student.cpp \
teacher.cpp \
widget.cpp
HEADERS += \
student.h \
teacher.h \
widget.h
TARGET = moneyorno
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
+11
View File
@@ -0,0 +1,11 @@
#include "student.h"
Student::Student(QWidget *parent) : QWidget(parent)
{
}
void Student::drink()
{
qDebug() << "请老师吃冷饮" << endl;
}
+20
View File
@@ -0,0 +1,20 @@
#ifndef STUDENT_H
#define STUDENT_H
#include <QWidget>
#include <QDebug>
class Student : public QWidget
{
Q_OBJECT
public:
explicit Student(QWidget *parent = nullptr);
public slots:
void drink();
signals:
};
#endif // STUDENT_H
+6
View File
@@ -0,0 +1,6 @@
#include "teacher.h"
Teacher::Teacher(QWidget *parent) : QWidget(parent)
{
}
+17
View File
@@ -0,0 +1,17 @@
#ifndef TEACHER_H
#define TEACHER_H
#include <QWidget>
class Teacher : public QWidget
{
Q_OBJECT
public:
explicit Teacher(QWidget *parent = nullptr);
signals:
void hot();
};
#endif // TEACHER_H
+69
View File
@@ -0,0 +1,69 @@
#include "widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
resize(500,300);
setWindowTitle("热了与冷饮");
n=0;
btn = new QPushButton("热了",this);
btn->setFixedSize(100,50);
btn->move(100,100);
btn2 = new QPushButton("没钱了",this);
btn2->setFixedSize(100,50);
btn2->move(100,200);
lable1 = new QLabel("显示",this);
lable1->setFixedSize(200,50);
lable1->move(250,100);
lable2 = new QLabel("请客次数: ",this);
lable2->setFixedSize(200,50);
lable2->move(250,200);
t1 = new Teacher();
s1 = new Student();
connect(t1,&Teacher::hot,s1,&Student::drink);
connect(btn,&QPushButton::clicked,this,&Widget::handleHot);
connect(btn2,&QPushButton::clicked,this,&Widget::noMoney);
emit t1->hot();
}
void Widget::handleHot()
{
emit t1->hot();
Widget::print();
}
void Widget::print()
{
n++;
if(n>0){
if(n%2==0)
lable1->setText("请老师吃巧乐兹");
else
lable1->setText("请老师吃老冰棍");
lable2->setText("请客次数: "+QString::number(n));
}
}
void Widget::noMoney()
{
n=0;
lable1->setText("请老师喝西北风");
lable2->setText("请客次数: "+QString::number(n));
}
Widget::~Widget()
{
}
+32
View File
@@ -0,0 +1,32 @@
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QPushButton>
#include <QLabel>
#include "teacher.h"
#include "student.h"
class Widget : public QWidget
{
Q_OBJECT
private:
Teacher *t1;
Student *s1;
int n;
private:
QPushButton *btn,*btn2;
QLabel *lable1,*lable2;
public slots:
void handleHot();
void print();
void noMoney();
public:
Widget(QWidget *parent = nullptr);
~Widget();
};
#endif // WIDGET_H
+46
View File
@@ -0,0 +1,46 @@
#include "custom.h"
Custom::Custom(QWidget *parent)
: QWidget(parent)
{
// 初始化窗口的控件
nameEdit = new QLineEdit(this);
nameEdit->resize(200,40);
nameEdit->move(10,10);
nEdit = new QLineEdit(this);
nEdit->resize(100,40);
nEdit->move(10,60);
toOrderBtn = new QPushButton("下单",this);
toOrderBtn->resize(80,40);
toOrderBtn->move(10,110);
eatStateLable = new QLabel("未开吃",this);
eatStateLable->resize(100,40);
eatStateLable->move(10,160);
// 设置按钮的点击事件的处理函数
connect(toOrderBtn,&QPushButton::clicked,this,&Custom::toOrderHandle);
}
void Custom::toOrderHandle()
{
eatStateLable->setText("等待上菜……");
// 下单按钮被点击了
qDebug() << "准备下单了";
qDebug() << "你的菜品: "<< nameEdit->text() << ", 数量:" << nEdit->text();
// 向店家发送信号,信号中包含菜品名和数量
emit toOrderSignal(nameEdit->text(), nEdit->text().toInt());
}
void Custom::okOrderHandle()
{
eatStateLable->setText(nameEdit->text()+"开吃……");
}
Custom::~Custom()
{
}
+32
View File
@@ -0,0 +1,32 @@
#ifndef CUSTOM_H
#define CUSTOM_H
#include <QWidget>
#include <QLineEdit>
#include <QPushButton>
#include <QLabel>
#include <QDebug>
class Custom : public QWidget
{
Q_OBJECT
private:
QLineEdit *nameEdit; // 菜品
QLineEdit *nEdit; // 数量
QPushButton *toOrderBtn; // 下单
QLabel *eatStateLable; // 开吃状态
public slots:
void toOrderHandle(); // 处理按钮的点击事件
void okOrderHandle(); // 店家上菜信号的处理函数
signals:
void toOrderSignal(QString name,int n);
public:
Custom(QWidget *parent = nullptr);
~Custom();
};
#endif // CUSTOM_H
+26
View File
@@ -0,0 +1,26 @@
#include "custom.h"
#include "restaurant.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Custom c;
c.setWindowTitle("点餐系统");
c.resize(800,600);
// 创建店类的对象
Restaurant r;
// 绑定客户下单信号处理函数
void (Custom:: *toOrder)(QString, int) = &Custom::toOrderSignal;
void (Restaurant:: *receiveOrder)(QString, int) = &Restaurant::receiveOrder;
QObject::connect(&c,toOrder,&r,receiveOrder);
// 绑定店家上菜信号和客户的槽函数
QObject::connect(&r,&Restaurant::okOrder,&c,&Custom::okOrderHandle);
c.show();
return a.exec();
}
+30
View File
@@ -0,0 +1,30 @@
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
custom.cpp \
restaurant.cpp
HEADERS += \
custom.h \
restaurant.h
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
+25
View File
@@ -0,0 +1,25 @@
#include "restaurant.h"
Restaurant::Restaurant(QWidget *parent) : QWidget(parent)
{
}
void Restaurant::receiveOrder(QString name, int n)
{
qDebug() << "店家已接收到菜单: " << name << ", 数量: " << n;
// 等待 10 秒
// QThread::msleep(10*1000); // 单位毫秒,UI阻塞
// 创建定时器,UI非阻塞
QTimer *timer = new QTimer();
// 绑定定时器的超时信号与 Lambda 表达式的匿名处理函数
QTimer::connect(timer,&QTimer::timeout,[&](){
qDebug() << "完成订单,上菜";
// 发送上菜的信号
emit okOrder();
});
timer->setSingleShot(true); // 单次使用
timer->start(10*1000); // 单位: 毫秒
}
+24
View File
@@ -0,0 +1,24 @@
#ifndef RESTAURANT_H
#define RESTAURANT_H
#include <QWidget>
#include <QTimer>
#include <QDebug>
#include "custom.h"
class Restaurant : public QWidget
{
Q_OBJECT
public:
explicit Restaurant(QWidget *parent = nullptr);
public slots:
// 接单的处理槽函数
void receiveOrder(QString name, int n);
signals:
void okOrder(); // 完成菜品
};
#endif // RESTAURANT_H
+42
View File
@@ -0,0 +1,42 @@
#include "awidget.h"
aWidget::aWidget(QWidget *parent)
: QWidget(parent)
{
// 设置A窗口实例的属性
setFixedSize(400,200);
setWindowTitle("A界面");
move(200,100);
// 新建B窗口对象
b = new bWidget();
b->setFixedSize(400,200);
b->setWindowTitle("B界面");
b->move(800,100);
// 新建“进入B”按钮,并设置其属性
btnToB = new QPushButton("进入B",this);
btnToB->resize(60,40);
// 绑定“进入B”按钮点击信号与“进入B界面并隐藏A界面”的槽函数
connect(btnToB,&QPushButton::clicked,this,&aWidget::toBHandle);
// 绑定“B界面返回A界面信号”与当前界面的“A界面显示并隐藏B界面”的槽函数
connect(b,&bWidget::returnASignal,this,&aWidget::returnAHandle);
}
void aWidget::toBHandle()
{
this->hide(); // 隐藏A界面
b->show(); // 显示B界面
}
void aWidget::returnAHandle()
{
b->hide(); // 隐藏B界面
this->show(); // 显示A界面
}
aWidget::~aWidget()
{
}
+32
View File
@@ -0,0 +1,32 @@
#ifndef AWIDGET_H
#define AWIDGET_H
#include <QWidget>
#include <QPushButton>
#include <QDebug>
#include "bwidget.h"
class aWidget : public QWidget
{
Q_OBJECT
private:
bWidget *b;
public slots:
void toBHandle();
void returnAHandle();
signals:
void toBSignal();
private:
QPushButton *btnToB;
public:
aWidget(QWidget *parent = nullptr);
~aWidget();
};
#endif // AWIDGET_H
+16
View File
@@ -0,0 +1,16 @@
#include "bwidget.h"
bWidget::bWidget(QWidget *parent) : QWidget(parent)
{
// 新建“返回A”按钮,并设置其属性
btnReturnA = new QPushButton("返回A",this);
btnReturnA->resize(60,40);
// 绑定“返回A”按钮点击事件与“发送返回A界面的信号”的槽函数
connect(btnReturnA,&QPushButton::clicked,this,&bWidget::sendReturnASignal);
}
void bWidget::sendReturnASignal()
{
emit returnASignal(); // 触发“返回A界面”信号
}
+28
View File
@@ -0,0 +1,28 @@
#ifndef BWIDGET_H
#define BWIDGET_H
#include <QWidget>
#include <QPushButton>
#include <QDebug>
class bWidget : public QWidget
{
Q_OBJECT
private:
QPushButton *btnReturnA;
public slots:
void sendReturnASignal();
signals:
void returnASignal();
public:
explicit bWidget(QWidget *parent = nullptr);
signals:
};
#endif // BWIDGET_H
+12
View File
@@ -0,0 +1,12 @@
#include "awidget.h"
#include "bwidget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication qa(argc, argv);
aWidget a; // 新建一个界面A对象a
a.show(); // 程序初始化运行时显示A对象a界面
return qa.exec();
}
+30
View File
@@ -0,0 +1,30 @@
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
bwidget.cpp \
main.cpp \
awidget.cpp
HEADERS += \
awidget.h \
bwidget.h
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
+11
View File
@@ -0,0 +1,11 @@
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
+34
View File
@@ -0,0 +1,34 @@
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
widget.cpp
HEADERS += \
widget.h
FORMS += \
widget.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
RESOURCES += \
res.qrc
+10
View File
@@ -0,0 +1,10 @@
<RCC>
<qresource prefix="/images">
<file alias="add">resources/add.png</file>
<file alias="mario">resources/mario.gif</file>
<file alias="open">resources/open.png</file>
<file alias="save">resources/save.png</file>
<file alias="sunny">resources/Sunny.jpg</file>
</qresource>
<qresource prefix="/videos"/>
</RCC>
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

+99
View File
@@ -0,0 +1,99 @@
#include "widget.h"
#include "ui_widget.h"
#include <QPixmap>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
n=0;
ui->setupUi(this);
// 设置 imageLable 的图片资源
QPixmap pixmap;
// : 开头表示引用 Qt 的资源文件
pixmap.load(":/images/mario"); // 加载像素图
ui->imageLable->resize(200,200);
ui->imageLable->setPixmap(pixmap); // 设置 QLable 显示图片
marioGif = new QMovie(":/images/mario");
ui->imageLable->setMovie(marioGif);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_hotBtn_clicked()
{
ui->whatLable->setText("巧乐兹");
}
void Widget::on_coldBtn_clicked()
{
ui->whatLable->setText("厚棉被");
}
void Widget::on_coldBtn_2_clicked()
{
}
void Widget::on_setTitleIconBtn_clicked()
{
n++;
if(n%2==0){
this->setWindowIcon(QIcon(":/images/save"));
this->setWindowTitle("标题被修改了");
showMaximized();
} else{
this->setWindowIcon(QIcon(""));
this->setWindowTitle("");
showNormal();
}
}
void Widget::on_showImg_pressed()
{
//ui->imageLable->hide();
marioGif->start();
}
void Widget::on_showImg_released()
{
marioGif->stop();
//ui->imageLable->show();
}
void Widget::on_setImgBtn_pressed()
{
QPixmap pixmap2;
pixmap2.load(":/images/sunny");
ui->showImg->setText("");
ui->showImg->setIconSize(QSize(200,200));
ui->showImg->setIcon(pixmap2);
}
void Widget::on_setImgBtn_released()
{
ui->showImg->setText("图片运输中");
ui->showImg->setIcon(QPixmap());
}
void Widget::on_setbgBtn_clicked()
{
// setStyleSheet("background-color: red; color: white; font-size: 16px;");
//setStyleSheet("background: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop:0 #FF0000, stop:0.17 #FF7F00, stop:0.33 #FFFF00, stop:0.5 #00FF00, stop:0.67 #0000FF, stop:0.83 #4B0082, stop:1 #8B00FF);");
//QString styleSheet = "background: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop:0.5 #000000, stop:0 #FF00F0,stop:1 #0F0F0F);";
//setStyleSheet(styleSheet);
showFullScreen();
}
+49
View File
@@ -0,0 +1,49 @@
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QMovie>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
private:
int n;
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_hotBtn_clicked();
void on_coldBtn_clicked();
void on_coldBtn_2_clicked();
void on_setTitleIconBtn_clicked();
void on_setImgBtn_clicked();
void on_showImg_pressed();
void on_showImg_released();
void on_setImgBtn_pressed();
void on_setImgBtn_released();
void on_setbgBtn_clicked(bool checked);
void on_setbgBtn_clicked();
private:
Ui::Widget *ui;
QMovie *marioGif;
};
#endif // WIDGET_H
+216
View File
@@ -0,0 +1,216 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Widget</class>
<widget class="QWidget" name="Widget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>654</width>
<height>476</height>
</rect>
</property>
<property name="cursor">
<cursorShape>OpenHandCursor</cursorShape>
</property>
<property name="windowTitle">
<string>Widget</string>
</property>
<property name="windowIcon">
<iconset resource="res.qrc">
<normaloff>:/images/open</normaloff>:/images/open</iconset>
</property>
<widget class="QPushButton" name="hotBtn">
<property name="geometry">
<rect>
<x>170</x>
<y>8</y>
<width>201</width>
<height>81</height>
</rect>
</property>
<property name="cursor">
<cursorShape>ClosedHandCursor</cursorShape>
</property>
<property name="styleSheet">
<string notr="true">font: 36pt &quot;华文隶书&quot;;
alternate-background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(9, 41, 4, 255), stop:0.085 rgba(2, 79, 0, 255), stop:0.19 rgba(50, 147, 22, 255), stop:0.275 rgba(236, 191, 49, 255), stop:0.39 rgba(243, 61, 34, 255), stop:0.555 rgba(135, 81, 60, 255), stop:0.667 rgba(121, 75, 255, 255), stop:0.825 rgba(164, 255, 244, 255), stop:0.885 rgba(104, 222, 71, 255), stop:1 rgba(93, 128, 0, 255));
color: rgb(255, 85, 255);</string>
</property>
<property name="text">
<string>热了</string>
</property>
<property name="iconSize">
<size>
<width>37</width>
<height>55</height>
</size>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>10</x>
<y>110</y>
<width>191</width>
<height>69</height>
</rect>
</property>
<property name="cursor">
<cursorShape>WhatsThisCursor</cursorShape>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(0, 170, 255);
font: 18pt &quot;华文琥珀&quot;;</string>
</property>
<property name="text">
<string>出门买啥?</string>
</property>
</widget>
<widget class="QLabel" name="whatLable">
<property name="geometry">
<rect>
<x>230</x>
<y>120</y>
<width>361</width>
<height>141</height>
</rect>
</property>
<property name="cursor">
<cursorShape>SizeBDiagCursor</cursorShape>
</property>
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(255, 85, 0);
color: rgb(255, 255, 255);
background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(255, 0, 0, 255), stop:0.166 rgba(255, 255, 0, 255), stop:0.333 rgba(0, 255, 0, 255), stop:0.5 rgba(0, 255, 255, 255), stop:0.666 rgba(0, 0, 255, 255), stop:0.833 rgba(255, 0, 255, 255), stop:1 rgba(255, 0, 0, 255));
font: 72pt &quot;华文彩云&quot;;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QPushButton" name="coldBtn">
<property name="geometry">
<rect>
<x>410</x>
<y>10</y>
<width>201</width>
<height>81</height>
</rect>
</property>
<property name="cursor">
<cursorShape>CrossCursor</cursorShape>
</property>
<property name="styleSheet">
<string notr="true">font: 36pt &quot;华文隶书&quot;;
selection-background-color: rgb(255, 170, 127);
color: rgb(170, 255, 255);</string>
</property>
<property name="text">
<string>冻着了</string>
</property>
</widget>
<widget class="QLabel" name="imageLable">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>20</x>
<y>260</y>
<width>121</width>
<height>121</height>
</rect>
</property>
<property name="cursor">
<cursorShape>WaitCursor</cursorShape>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QPushButton" name="setImgBtn">
<property name="geometry">
<rect>
<x>240</x>
<y>300</y>
<width>191</width>
<height>49</height>
</rect>
</property>
<property name="cursor">
<cursorShape>SizeHorCursor</cursorShape>
</property>
<property name="styleSheet">
<string notr="true">font: 28pt &quot;华文隶书&quot;;
</string>
</property>
<property name="text">
<string>设置图片</string>
</property>
</widget>
<widget class="QPushButton" name="setTitleIconBtn">
<property name="geometry">
<rect>
<x>240</x>
<y>400</y>
<width>191</width>
<height>49</height>
</rect>
</property>
<property name="cursor">
<cursorShape>UpArrowCursor</cursorShape>
</property>
<property name="styleSheet">
<string notr="true">font: 18pt &quot;华文隶书&quot;;
</string>
</property>
<property name="text">
<string>标题Icon修改</string>
</property>
</widget>
<widget class="QPushButton" name="showImg">
<property name="geometry">
<rect>
<x>440</x>
<y>280</y>
<width>201</width>
<height>181</height>
</rect>
</property>
<property name="cursor">
<cursorShape>ForbiddenCursor</cursorShape>
</property>
<property name="text">
<string>图片正在派送中</string>
</property>
</widget>
<widget class="QPushButton" name="setbgBtn">
<property name="geometry">
<rect>
<x>20</x>
<y>40</y>
<width>141</width>
<height>49</height>
</rect>
</property>
<property name="cursor">
<cursorShape>UpArrowCursor</cursorShape>
</property>
<property name="styleSheet">
<string notr="true">font: 18pt &quot;华文隶书&quot;;
</string>
</property>
<property name="text">
<string>背景修改</string>
</property>
</widget>
</widget>
<resources>
<include location="res.qrc"/>
</resources>
<connections/>
</ui>
+11
View File
@@ -0,0 +1,11 @@
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
+34
View File
@@ -0,0 +1,34 @@
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
widget.cpp
HEADERS += \
widget.h
FORMS += \
widget.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
RESOURCES += \
res.qrc
+5
View File
@@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/movies">
<file alias="yanhua">resources/yanhua1.gif</file>
</qresource>
</RCC>
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

+47
View File
@@ -0,0 +1,47 @@
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 加载动画资源
yanhuagif = new QMovie(":/movies/yanhua");
srand(time(NULL));
randNum = rand() % 10; // 0-9的数
// 开启定时器, 用于定时换随机数
timer = new QTimer();
connect(timer,&QTimer::timeout,[&](){
randNum = rand() % 10;
});
timer->start(5*1000); // 5秒
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
guessNum = ui->numEdit->text().toInt();
qDebug() << "随机数:" << randNum << "输入的数" << guessNum << endl;
QString resStr = "随机数: "+ QString::number(randNum)+ ", 你输入的数: "+QString::number(guessNum);
ui->tipesLable->setText("本轮结果: " + resStr);
if(guessNum == randNum){
ui->resaultShowLabel->setMovie(yanhuagif);
yanhuagif->start();
} else {
if(yanhuagif->state() == QMovie::Running)
yanhuagif->stop();
ui->resaultShowLabel->setText(" ");
}
}
+32
View File
@@ -0,0 +1,32 @@
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QMovie>
#include <QDebug>
#include <QTimer>
#include <cstdlib>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_pushButton_clicked();
private:
Ui::Widget *ui;
int guessNum = 0;
int randNum = 0;
QMovie *yanhuagif;
QTimer *timer;
};
#endif // WIDGET_H
+133
View File
@@ -0,0 +1,133 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Widget</class>
<widget class="QWidget" name="Widget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>500</width>
<height>400</height>
</rect>
</property>
<property name="windowTitle">
<string>Widget</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLineEdit" name="numEdit">
<property name="styleSheet">
<string notr="true">padding:5px;
font: 18pt &quot;Agency FB&quot;;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="styleSheet">
<string notr="true">font: 18pt &quot;Agency FB&quot;;</string>
</property>
<property name="text">
<string>猜一猜</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="tipesLable">
<property name="styleSheet">
<string notr="true">font: 14pt &quot;宋体&quot;;
color: rgb(170, 170, 255);</string>
</property>
<property name="text">
<string>结果: </string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="resaultShowLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
+15
View File
@@ -0,0 +1,15 @@
#include "mainwidget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWidget mainWidget;
mainWidget.setWindowTitle("猜拳");
mainWidget.setWindowIcon(QIcon(":/imgs/rock"));
mainWidget.show();
return a.exec();
}
+159
View File
@@ -0,0 +1,159 @@
#include "mainwidget.h"
#include "ui_mainwidget.h"
MainWidget::MainWidget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::MainWidget)
{
ui->setupUi(this);
rockImg = new QPixmap(":/imgs/rock"); // 随机数为 0 时, 加载拳头
paperImg = new QPixmap(":/imgs/paper"); // 随机数为 1 时, 加载布
scissorsImg = new QPixmap(":/imgs/scissors"); // 随机数为 2 时, 加载剪刀
// 电脑初始化时加载的图片
QPixmap firstImg;
firstImg.load(":/imgs/scissors");
ui->randImgsLable->setPixmap(firstImg);
// 初始化计分板数据
numsOfGame = 0;
currentScore = 0;
// 随机函数定义
srand(time(NULL)); // 随时间变化的随机种子
timer = new QTimer();
connect(timer,&QTimer::timeout,[&](){
randNum = rand() % 3; // 在 0-2 之间随机取值
QPixmap nowImg = switchImgs(randNum); // 根据当前的随机值加载图片
ui->randImgsLable->setPixmap(nowImg); // 将当前随机值对应的图片设置到主界面
// 调试信息
qDebug() << "numsOfGame: " << numsOfGame <<", randNum: "<<randNum
<<", playerInputNum: "<<playerInputNum<<endl;
});
}
MainWidget::~MainWidget()
{
delete ui;
}
void MainWidget::on_startGameBtn_clicked()
{
numsOfGame++;
timer->start(0.05*1000); // 50ms
// 更新游戏次数
ui->numsOfGameLable->setText("游戏次数: " + QString::number(numsOfGame));
}
QPixmap MainWidget::switchImgs(int randNum)
{
switch (randNum) {
case rock:
return *rockImg; // 随机数为 0 时, 加载拳头
break;
case paper:
return *paperImg; // 随机数为 1 时, 加载布
break;
case scissors:
return *scissorsImg; // 随机数为 2 时, 加载剪刀
break;
default:
return *paperImg; // 默认加载布
break;
}
}
void MainWidget::on_rockBtn_clicked()
{
// 当计数器状态为 false, 即计时器当前已经是 stop 状态时, 点击当前按钮时, 直接返回, 不进行其他逻辑操作
if(timer->isActive() == false){
return;
}
timer->stop(); // 随机数生成的计数器停止
playerInputNum = rock; // 玩家出拳
// 则玩家赢加 10 分, 输减 3 分, 平局不得分
if(randNum == scissors){
currentScore+=10;
} else if(randNum == paper) {
currentScore-=3;
}
// 调试信息
qDebug() << "numsOfGame: " << numsOfGame <<", randNum: "<<randNum
<<", playerInputNum: "<<playerInputNum<<endl;
// 更新计分板
ui->currentScoreLable->setText("当前得分: " + QString::number(currentScore));
}
void MainWidget::on_paperBtn_clicked()
{
// 当计数器状态为 false, 即计时器当前已经是 stop 状态时, 点击当前按钮时, 直接返回, 不进行其他逻辑操作
if(timer->isActive() == false){
return;
}
timer->stop(); // 随机数生成的计数器停止
playerInputNum = paper; // 玩家出布
// 则玩家赢加 10 分, 输减 3 分, 平局不得分
if(randNum == rock){
currentScore+=10;
} else if(randNum == scissors) {
currentScore-=3;
}
// 调试信息
qDebug() << "numsOfGame: " << numsOfGame <<", randNum: "<<randNum
<<", playerInputNum: "<<playerInputNum<<endl;
// 更新计分板
ui->currentScoreLable->setText("当前得分: " + QString::number(currentScore));
}
void MainWidget::on_scissorsBtn_clicked()
{
// 当计数器状态为 false, 即计时器当前已经是 stop 状态时, 点击当前按钮时, 直接返回, 不进行其他逻辑操作
if(timer->isActive() == false){
return;
}
timer->stop(); // 随机数生成的计数器停止
playerInputNum = scissors; // 玩家出剪刀
// 则玩家赢加 10 分, 输减 3 分, 平局不得分
if(randNum == paper){
currentScore+=10;
} else if(randNum == rock) {
currentScore-=3;
}
// 调试信息
qDebug() << "numsOfGame: " << numsOfGame <<", randNum: "<<randNum
<<", playerInputNum: "<<playerInputNum<<endl;
// 更新计分板
ui->currentScoreLable->setText("当前得分: " + QString::number(currentScore));
}
void MainWidget::on_clearBtn_clicked()
{
timer->stop(); // 随机数生成的计数器停止
// 统计数据重置为 0
currentScore = 0;
numsOfGame = 0;
// 更新游戏次数
ui->numsOfGameLable->setText("游戏次数: ");
// 更新计分板
ui->currentScoreLable->setText("当前得分: ");
// 调试信息
qDebug() << "numsOfGame: " << numsOfGame <<", randNum: "<<randNum
<<", playerInputNum: "<<playerInputNum<<endl;
}
+54
View File
@@ -0,0 +1,54 @@
#ifndef MAINWIDGET_H
#define MAINWIDGET_H
#include <QWidget>
#include <QIcon>
#include <QPixmap>
#include <QTimer>
#include <QDebug>
#include <cstdlib>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWidget; }
QT_END_NAMESPACE
class MainWidget : public QWidget
{
Q_OBJECT
public:
MainWidget(QWidget *parent = nullptr);
~MainWidget();
private:
Ui::MainWidget *ui;
QPixmap switchImgs(int); // 切换电脑图片函数
private:
int randNum; // 电脑出招映射的随机数 0, 1, 2
int playerInputNum; // 玩家点击的按钮映射的数值 0, 1, 2
QTimer *timer; // 计时器
// QPixmap *randImg; // 随机的电脑出招图片
int numsOfGame; // 游戏次数
int currentScore; // 当前得分
QPixmap *rockImg; // 拳头
QPixmap *paperImg; // 布
QPixmap *scissorsImg; // 剪刀
public:
// 定义枚举: 0-拳、1-布、2-剪刀
enum{
rock,
paper,
scissors
};
private slots:
void on_startGameBtn_clicked();
void on_rockBtn_clicked();
void on_paperBtn_clicked();
void on_scissorsBtn_clicked();
void on_clearBtn_clicked();
};
#endif // MAINWIDGET_H
+431
View File
@@ -0,0 +1,431 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWidget</class>
<widget class="QWidget" name="MainWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWidget</string>
</property>
<property name="styleSheet">
<string notr="true">background-color: qconicalgradient(cx:0, cy:0, angle:135, stop:0 rgba(255, 255, 0, 69), stop:0.375 rgba(255, 255, 0, 69), stop:0.423533 rgba(251, 255, 0, 145), stop:0.45 rgba(247, 255, 0, 208), stop:0.477581 rgba(255, 244, 71, 130), stop:0.518717 rgba(255, 218, 71, 130), stop:0.55 rgba(255, 255, 0, 255), stop:0.57754 rgba(255, 203, 0, 130), stop:0.625 rgba(255, 255, 0, 69), stop:1 rgba(255, 255, 0, 69));</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QWidget" name="widget_3" native="true">
<property name="maximumSize">
<size>
<width>500</width>
<height>500</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(0, 170, 255);</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<spacer name="horizontalSpacer_11">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<spacer name="horizontalSpacer_13">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="randImgsLable">
<property name="maximumSize">
<size>
<width>500</width>
<height>500</height>
</size>
</property>
<property name="baseSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="text">
<string/>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_14">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<spacer name="horizontalSpacer_12">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<spacer name="horizontalSpacer_10">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="0" column="2">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_9">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QWidget" name="widget_4" native="true">
<property name="styleSheet">
<string notr="true">background-color: rgb(255, 85, 0);</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="rockBtn">
<property name="maximumSize">
<size>
<width>130</width>
<height>130</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="res.qrc">
<normaloff>:/imgs/rock</normaloff>:/imgs/rock</iconset>
</property>
<property name="iconSize">
<size>
<width>130</width>
<height>130</height>
</size>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="paperBtn">
<property name="maximumSize">
<size>
<width>130</width>
<height>130</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="res.qrc">
<normaloff>:/imgs/paper</normaloff>:/imgs/paper</iconset>
</property>
<property name="iconSize">
<size>
<width>130</width>
<height>130</height>
</size>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="scissorsBtn">
<property name="maximumSize">
<size>
<width>130</width>
<height>130</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="res.qrc">
<normaloff>:/imgs/scissors</normaloff>:/imgs/scissors</iconset>
</property>
<property name="iconSize">
<size>
<width>130</width>
<height>130</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_8">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QWidget" name="widget_2" native="true">
<property name="styleSheet">
<string notr="true">background-color: rgb(85, 255, 255);</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="numsOfGameLable">
<property name="styleSheet">
<string notr="true">font: 18pt &quot;黑体&quot;;</string>
</property>
<property name="text">
<string>游戏次数: </string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="currentScoreLable">
<property name="styleSheet">
<string notr="true">font: 18pt &quot;黑体&quot;;</string>
</property>
<property name="text">
<string>当前得分: </string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="startGameBtn">
<property name="styleSheet">
<string notr="true">font: 18pt &quot;黑体&quot;;
color: rgb(255, 0, 0);</string>
</property>
<property name="text">
<string>开始游戏</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="clearBtn">
<property name="styleSheet">
<string notr="true">font: 18pt &quot;黑体&quot;;
color: rgb(255, 0, 0);</string>
</property>
<property name="text">
<string>清零</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="res.qrc"/>
</resources>
<connections/>
</ui>
+7
View File
@@ -0,0 +1,7 @@
<RCC>
<qresource prefix="/imgs">
<file alias="paper">resources/paper.png</file>
<file alias="rock">resources/rock.png</file>
<file alias="scissors">resources/scissors.png</file>
</qresource>
</RCC>
Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

+34
View File
@@ -0,0 +1,34 @@
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
mainwidget.cpp
HEADERS += \
mainwidget.h
FORMS += \
mainwidget.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
RESOURCES += \
res.qrc
+13
View File
@@ -0,0 +1,13 @@
cc = g++
cflags = -Wall -lssl -lcrypto -lcurl -ljsoncpp
cflags += -I/home/flykhan/.tools/openssl_build/include/
cflags += -I/home/flykhan/.tools/curl/include/
cflags += -I/home/flykhan/.tools/jsoncpp-Sandbox/jsoncpp-build/include/
cflags += -L/home/flykhan/.tools/openssl_build/lib/
cflags += -L/home/flykhan/.tools/curl/lib/
cflags += -L/home/flykhan/.tools/jsoncpp-Sandbox/jsoncpp-build/lib/
main: main.cpp
$(cc) main.cpp -o main $(cflags) -std=c++14
clean:
rm *.o main -rf
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 502 KiB

+264
View File
@@ -0,0 +1,264 @@
/**
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* @author baidu aip
*/
#ifndef __AIP_BASE_H__
#define __AIP_BASE_H__
#include <memory>
#include <cstring>
#include "http.h"
#include "json/json.h"
#include "base64.h"
#include "curl/curl.h"
#include "utils.h"
namespace aip {
static const char* AIP_SDK_VERSION = "0.3.3";
static const char* CURL_ERROR_CODE = "curl_error_code";
static const std::string ACCESS_TOKEN_URL = "https://aip.baidubce.com/oauth/2.0/token";
static const std::map<std::string, std::string> null;
class AipBase
{
private:
std::string _app_id;
int _expired_time;
bool _is_bce;
bool _has_decide_type;
std::string _scope;
protected:
std::string getAccessToken()
{
time_t now = time(NULL);
if (!access_token.empty())
{
return this->access_token;
}
if (now < this->_expired_time - 60 * 60 * 24)
{
return this->access_token;
}
std::string response;
std::map<std::string, std::string> params;
params["grant_type"] = "client_credentials";
params["client_id"] = this->ak;
params["client_secret"] = this->sk;
int status_code = this->client.get(
ACCESS_TOKEN_URL,
&params,
nullptr,
&response
);
Json::Value obj;
if (status_code != CURLcode::CURLE_OK) {
obj[CURL_ERROR_CODE] = status_code;
return obj.toStyledString();
}
std::string error;
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
this->access_token = obj["access_token"].asString();
this->_expired_time = obj["expires_in"].asInt() + (int) now;
this->_scope = obj["scope"].asString();
return this->access_token;
}
public:
std::string ak;
std::string sk;
HttpClient client;
Json::CharReaderBuilder crbuilder;
std::string access_token;
AipBase(const std::string & app_id, const std::string & ak, const std::string & sk):
_app_id(app_id),
_is_bce(false),
_has_decide_type(false),
ak(ak),
sk(sk)
{
if (_app_id == "")
{
}
}
void setConnectionTimeoutInMillis(int connect_timeout)
{
this->client.setConnectTimeout(connect_timeout);
}
void setSocketTimeoutInMillis(int socket_timeout)
{
this->client.setSocketTimeout(socket_timeout);
}
void setDebug(bool debug)
{
this->client.setDebug(debug);
}
std::string getAk() {
return ak;
}
Json::Value request(
std::string url,
std::map<std::string, std::string> const & params,
std::string const & data,
std::map<std::string, std::string> const & headers)
{
std::string response;
Json::Value obj;
std::string body;
auto headers_for_sign = headers;
auto temp_params = params;
temp_params["charset"] = "UTF-8";
this->prepare_request(url, temp_params, headers_for_sign);
int status_code = this->client.post(url, &temp_params, data, &headers_for_sign, &response);
if (status_code != CURLcode::CURLE_OK) {
obj[CURL_ERROR_CODE] = status_code;
return obj;
}
std::string error;
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
return obj;
}
Json::Value request(
std::string url,
std::map<std::string, std::string> const & params,
std::map<std::string, std::string> const & data,
std::map<std::string, std::string> const & headers)
{
std::string response;
Json::Value obj;
auto headers_for_sign = headers;
auto temp_params = params;
this->prepare_request(url, temp_params, headers_for_sign);
int status_code = this->client.post(url, &temp_params, data, &headers_for_sign, &response);
if (status_code != CURLcode::CURLE_OK) {
obj[CURL_ERROR_CODE] = status_code;
return obj;
}
std::string error;
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
return obj;
}
void prepare_request(std::string url,
std::map<std::string, std::string> & params,
std::map<std::string, std::string> & headers)
{
params["aipSdk"] = "C";
params["aipSdkVersion"] = AIP_SDK_VERSION;
if (_has_decide_type) {
if (_is_bce) {
std::string method = "POST";
sign(method, url, params, headers, ak, sk);
} else {
params["access_token"] = this->getAccessToken();
}
return;
}
if (getAccessToken() == "") {
_is_bce = true;
} else {
const char * t = std::strstr(this->_scope.c_str(), "brain_all_scope");
if (t == NULL)
{
_is_bce = true;
}
}
_has_decide_type = true;
prepare_request(url, params, headers);
}
Json::Value requestjson(
std::string url,
Json::Value & data,
std::map<std::string, std::string> & params,
std::map<std::string, std::string> const & headers)
{
std::string response;
Json::Value obj;
auto headers_for_sign = headers;
auto temp_params = params;
this->prepare_request(url, temp_params, headers_for_sign);
int status_code = this->client.post(url, nullptr, data, nullptr, &response);
if (status_code != CURLcode::CURLE_OK) {
obj[aip::CURL_ERROR_CODE] = status_code;
return obj;
}
std::string error;
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
return obj;
}
Json::Value request_com(
std::string const & url,
Json::Value & data)
{
std::string response;
Json::Value obj;
int status_code = this->client.post(url, nullptr, data, nullptr, &response);
if (status_code != CURLcode::CURLE_OK) {
obj[aip::CURL_ERROR_CODE] = status_code;
return obj;
}
std::string error;
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
return obj;
}
};
}
#endif
+130
View File
@@ -0,0 +1,130 @@
/**
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* @author baidu aip
*/
#ifndef __AIP_BASE64_H__
#define __AIP_BASE64_H__
#include <iostream>
#include <string>
namespace aip {
static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
static inline bool is_base64(const char c)
{
return (isalnum(c) || (c == '+') || (c == '/'));
}
std::string base64_encode(const char * bytes_to_encode, unsigned int in_len)
{
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
while (in_len--)
{
char_array_3[i++] = *(bytes_to_encode++);
if(i == 3)
{
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(i = 0; (i <4) ; i++)
{
ret += base64_chars[char_array_4[i]];
}
i = 0;
}
}
if(i)
{
for(j = i; j < 3; j++)
{
char_array_3[j] = '\0';
}
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(j = 0; (j < i + 1); j++)
{
ret += base64_chars[char_array_4[j]];
}
while((i++ < 3))
{
ret += '=';
}
}
return ret;
}
std::string base64_decode(std::string const & encoded_string)
{
int in_len = (int) encoded_string.size();
int i = 0;
int j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std::string ret;
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_]; in_++;
if (i ==4) {
for (i = 0; i <4; i++)
char_array_4[i] = base64_chars.find(char_array_4[i]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (i = 0; (i < 3); i++)
ret += char_array_3[i];
i = 0;
}
}
if (i) {
for (j = i; j <4; j++)
char_array_4[j] = 0;
for (j = 0; j <4; j++)
char_array_4[j] = base64_chars.find(char_array_4[j]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
}
return ret;
}
}
#endif
+234
View File
@@ -0,0 +1,234 @@
/**
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* @author baidu aip
*/
#ifndef __AIP_HTTP_H__
#define __AIP_HTTP_H__
#include "curl/curl.h"
#include <sstream>
#include <string>
#include <map>
#include <json/json.h>
namespace aip {
inline size_t onWriteData(void * buffer, size_t size, size_t nmemb, void * userp)
{
std::string * str = dynamic_cast<std::string *>((std::string *)userp);
str->append((char *)buffer, size * nmemb);
return nmemb;
}
class HttpClient
{
private:
bool debug = false;
int connect_timeout = 10000;
int socket_timeout = 10000;
void makeUrlencodedForm(std::map<std::string, std::string> const & params, std::string * content) const
{
content->clear();
std::map<std::string, std::string>::const_iterator it;
for(it=params.begin(); it!=params.end(); it++)
{
char * key = curl_escape(it->first.c_str(), (int) it->first.size());
char * value = curl_escape(it->second.c_str(),(int) it->second.size());
*content += key;
*content += '=';
*content += value;
*content += '&';
curl_free(key);
curl_free(value);
}
}
void appendUrlParams(std::map<std::string, std::string> const & params, std::string* url) const
{
if(params.empty()) {
return;
}
std::string content;
this->makeUrlencodedForm(params, &content);
bool url_has_param = false;
for (const auto& ch : *url) {
if (ch == '?') {
url_has_param = true;
break;
}
}
if (url_has_param) {
url->append("&");
} else {
url->append("?");
}
url->append(content);
}
void appendHeaders(std::map<std::string, std::string> const & headers, curl_slist ** slist) const
{
std::ostringstream ostr;
std::map<std::string, std::string>::const_iterator it;
for(it=headers.begin(); it!=headers.end(); it++)
{
ostr << it->first << ":" << it->second;
*slist = curl_slist_append(*slist, ostr.str().c_str());
ostr.str("");
}
}
public:
HttpClient() = default;
HttpClient(const HttpClient &) = delete;
HttpClient & operator=(const HttpClient &) = delete;
void setConnectTimeout(int connect_timeout)
{
this->connect_timeout = connect_timeout;
}
void setSocketTimeout(int socket_timeout)
{
this->socket_timeout = socket_timeout;
}
void setDebug(bool debug)
{
this->debug = debug;
}
int get(
std::string url,
std::map<std::string, std::string> const * params,
std::map<std::string, std::string> const * headers,
std::string * response) const
{
CURL * curl = curl_easy_init();
struct curl_slist * slist = NULL;
if (headers) {
this->appendHeaders(*headers, &slist);
}
if (params) {
this->appendUrlParams(*params, &url);
}
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, onWriteData);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) response);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, true);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, this->connect_timeout);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, this->socket_timeout);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
curl_easy_setopt(curl, CURLOPT_VERBOSE, this->debug);
int status_code = curl_easy_perform(curl);
curl_easy_cleanup(curl);
curl_slist_free_all(slist);
return status_code;
}
int post(
std::string url,
std::map<std::string, std::string> const * params,
const std::string & body,
std::map<std::string, std::string> const * headers,
std::string * response) const
{
struct curl_slist * slist = NULL;
CURL * curl = curl_easy_init();
if (headers) {
this->appendHeaders(*headers, &slist);
}
if (params) {
this->appendUrlParams(*params, &url);
}
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
curl_easy_setopt(curl, CURLOPT_POST, true);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, body.size());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, onWriteData);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) response);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, true);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, this->connect_timeout);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, this->socket_timeout);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
curl_easy_setopt(curl, CURLOPT_VERBOSE, this->debug);
int status_code = curl_easy_perform(curl);
curl_easy_cleanup(curl);
curl_slist_free_all(slist);
return status_code;
}
int post(
std::string url,
std::map<std::string, std::string> const * params,
std::map<std::string, std::string> const & data,
std::map<std::string, std::string> const * headers,
std::string * response) const
{
std::string body;
this->makeUrlencodedForm(data, &body);
return this->post(std::move(url), params, body, headers, response);
}
int post(
std::string url,
std::map<std::string, std::string> const * params,
Json::Value const & data,
std::map<std::string, std::string> const * headers,
std::string * response) const
{
std::string body;
Json::StreamWriterBuilder swb;
std::unique_ptr<Json::StreamWriter> writer(swb.newStreamWriter());
std::ostringstream os;
writer->write(data, &os);
body = os.str();
std::map<std::string, std::string> temp_headers;
if (headers) {
std::map<std::string, std::string> temp_headers(*headers);
}
temp_headers["Content-Type"] = "application/json";
return this->post(url.c_str(), params, body, &temp_headers, response);
}
int post(
std::string url,
std::map<std::string, std::string> const * params,
std::map<std::string, std::string> const * headers,
std::string * response) const
{
const static std::string EMPTY_STRING;
return this->post(std::move(url), params, EMPTY_STRING, headers, response);
}
};
}
#endif
+283
View File
@@ -0,0 +1,283 @@
/**
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* @author baidu aip
*/
#ifndef __AIP_UTILS_H__
#define __AIP_UTILS_H__
#include <string>
#include <fstream>
#include <ctype.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <algorithm>
#include <openssl/md5.h>
const int __BCE_VERSION__ = 1;
const int __BCE_EXPIRE__ = 1800;
namespace aip {
template<class CharT, class Traits, class Allocator>
std::basic_istream<CharT, Traits>& getall(std::basic_istream<CharT, Traits>& input,
std::basic_string<CharT, Traits, Allocator>& str) {
std::ostringstream oss;
oss << input.rdbuf();
str.assign(oss.str());
return input;
}
inline int get_file_content(const char *filename, std::string* out) {
std::ifstream in(filename, std::ios::in | std::ios::binary);
if (in) {
getall(in, *out);
return 0;
} else {
return -1;
}
}
inline std::string to_upper(std::string src)
{
std::transform(src.begin(), src.end(), src.begin(), toupper);
return src;
}
inline std::string to_lower(std::string src)
{
std::transform(src.begin(), src.end(), src.begin(), tolower);
return src;
}
inline std::string to_hex(unsigned char c, bool lower = false)
{
const std::string hex = "0123456789ABCDEF";
std::stringstream ss;
ss << hex[c >> 4] << hex[c & 0xf];
return lower ? to_lower(ss.str()) : ss.str();
}
inline time_t now()
{
return time(NULL);
}
std::string utc_time(time_t timestamp)
{
struct tm result_tm;
char buffer[32];
#ifdef _WIN32
gmtime_s(&result_tm, &timestamp);
#else
gmtime_r(&timestamp, &result_tm);
#endif
size_t size = strftime(buffer, 32, "%Y-%m-%dT%H:%M:%SZ", &result_tm);
return std::string(buffer, size);
}
void url_parse(
const std::string & url,
std::map<std::string, std::string> & params)
{
int pos = (int)url.find("?");
if (pos != -1)
{
int key_start = pos + 1,
key_len = 0,
val_start = 0;
for (int i = key_start; i <= (int)url.size(); ++i)
{
switch (url[i])
{
case '=':
key_len = i - key_start;
val_start = i + 1;
break;
case '\0':
case '&':
if (key_len != 0)
{
params[url.substr(key_start, key_len)] = url.substr(val_start, i - val_start);
key_start = i + 1;
key_len = 0;
}
break;
default:
break;
}
}
}
}
std::string url_encode(const std::string & input, bool encode_slash=true)
{
std::stringstream ss;
const char *str = input.c_str();
for (uint32_t i = 0; i < input.size(); i++)
{
unsigned char c = str[i];
if (isalnum(c) || c == '_' || c == '-' || c == '~' || c == '.' || (!encode_slash && c == '/'))
{
ss << c;
}
else
{
ss << "%" << to_hex(c);
}
}
return ss.str();
}
std::string canonicalize_params(std::map<std::string, std::string> & params)
{
std::vector<std::string> v;
v.reserve(params.size());
for (auto & it : params) {
v.push_back(url_encode(it.first) + "=" + url_encode(it.second));
}
std::sort(v.begin(), v.end());
std::string result;
for (auto & it : v)
{
result.append((result.empty() ? "" : "&") + it);
}
return result;
}
std::string canonicalize_headers(std::map<std::string, std::string> & headers)
{
std::vector<std::string> v;
v.reserve(headers.size());
for (auto & it : headers) {
v.push_back(url_encode(to_lower(it.first)) + ":" + url_encode(it.second));
}
std::sort(v.begin(), v.end());
std::string result;
for (auto & it : v)
{
result.append((result.empty() ? "" : "\n") + it);
}
return result;
}
std::string get_headers_keys(std::map<std::string, std::string> & headers)
{
std::vector<std::string> v;
v.reserve(headers.size());
for (auto & it : headers) {
v.push_back(to_lower(it.first));
}
std::string result;
for (auto & it : v)
{
result.append((result.empty() ? "" : ";") + it);
}
return result;
}
std::string get_host(const std::string & url)
{
int pos = (int)url.find("://") + 3;
return url.substr(
pos,
url.find('/', pos) - pos
);
}
std::string get_path(const std::string & url)
{
int path_start = (int)url.find('/', url.find("://") + 3);
int path_end = (int)url.find('?');
path_end = path_end == -1 ? (int)url.size() : path_end;
return url.substr(path_start, path_end - path_start);
}
std::string hmac_sha256(
const std::string & src,
const std::string & sk)
{
const EVP_MD *evp_md = EVP_sha256();
unsigned char md[EVP_MAX_MD_SIZE];
unsigned int md_len = 0;
if (HMAC(evp_md,
reinterpret_cast<const unsigned char *>(sk.data()), (int)sk.size(),
reinterpret_cast<const unsigned char *>(src.data()), src.size(),
md, &md_len) == NULL)
{
return "";
}
std::stringstream ss;
for (int i = 0; i < (int)md_len; ++i)
{
ss << to_hex(md[i], true);
}
return ss.str();
}
void sign(
std::string method,
std::string & url,
std::map<std::string, std::string> & params,
std::map<std::string, std::string> & headers,
std::string & ak,
std::string & sk)
{
url_parse(url, params);
headers["Host"] = get_host(url);
std::string timestamp = utc_time(now());
headers["x-bce-date"] = timestamp;
std::stringstream ss;
ss << "bce-auth-v" << __BCE_VERSION__ << "/" << ak << "/"
<< timestamp << "/" << __BCE_EXPIRE__;
std::string val = ss.str();
std::string sign_key = hmac_sha256(val, sk);
ss.str("");
ss << to_upper(method) << '\n' << url_encode(get_path(url), false)
<< '\n' << canonicalize_params(params)
<< '\n' << canonicalize_headers(headers);
std::string signature = hmac_sha256(ss.str(), sign_key);
ss.str("");
ss << "bce-auth-v" << __BCE_VERSION__ << "/" << ak << "/"
<< timestamp << "/" << __BCE_EXPIRE__ << "/"
<< get_headers_keys(headers) << "/" << signature;
headers["authorization"] = ss.str();
}
}
#endif
+38
View File
@@ -0,0 +1,38 @@
#include <iostream>
#include "ocr.h" // 用于调用接口
#include <string> // 用于 string 的操作
#include <codecvt> // 用于转码
using namespace std;
int main(int argc, char const *argv[]) // argc: 参数个数, argv: 参数列表
{
if (argc < 2)
{
cout << "Usage: " << argv[0] << "车牌照片路径" << endl;
return -1;
}
string app_id = "35458273"; // 你的 App ID
string api_key = "i45yQx4IaGoxxULLDVPl4iNj"; // 你的 Api Key
string secret_key = "jnt90aTbXCOp9L7gRB1xq1C3iT0bLuie"; // 你的 Secret Key
aip::Ocr client(app_id, api_key, secret_key); // 新建一个对象, 用于调用接口, 调用通用文字识别, 图片参数为本地图片
cout << "ok" << endl;
// 定义 json 格式的数据类型 Value, result 是 json 类型的 Value 类实例, 用于存储返回的结果
Json::Value result;
string image;
// 加载本地的车牌图片内容到 image 对象中, 用于调用车牌识别
// aip::get_file_content("R-C.jpg", &image);
aip::get_file_content(argv[1], &image);
// 客户端发送图片内容到百度服务器, 并返回结果到 result 对象中
result = client.license_plate(image, aip::null);
// cout << result << endl;
cout << "车牌颜色: " << result["words_result"]["color"] << endl;
cout << "车牌号码: " << result["words_result"]["number"].asString() << endl;
return 0;
}
+1551
View File
File diff suppressed because it is too large Load Diff
+20
View File
@@ -0,0 +1,20 @@
cc = g++
cflags = -Wall -lssl -lcrypto -lcurl -ljsoncpp
cflags += -I/home/flykhan/.tools/openssl_build/include/
cflags += -I/home/flykhan/.tools/curl/include/
cflags += -I/home/flykhan/.tools/jsoncpp-Sandbox/jsoncpp-build/include/
cflags += -L/home/flykhan/.tools/openssl_build/lib/
cflags += -L/home/flykhan/.tools/curl/lib/
cflags += -L/home/flykhan/.tools/jsoncpp-Sandbox/jsoncpp-build/lib/
idCard:
$(cc) idCard.cpp -o idCard $(cflags) -std=c++14
bankCard:
$(cc) bankCard.cpp -o bankCard $(cflags) -std=c++14
driverLicense:
$(cc) driverLicense.cpp -o driverLicense $(cflags) -std=c++14
clean:
rm *.o idCard bankCard driverLicense -rf
+55
View File
@@ -0,0 +1,55 @@
#include <iostream>
#include "ocr.h" // 用于调用接口
using namespace std;
string cardType(int);
int main(int argc, char const *argv[])
{
if (argc < 2)
{
cout << "用法: " << argv[0] << " 银行卡照片" << endl;
return -1; // 返回 -1 表示程序异常退出
}
string app_id = "35475147"; // 你的 App ID
string api_key = "CSneGCoRs8zMD1F1PPnXyzPP"; // 你的 Api Key
string secret_key = "wlKjVS2lE9xPFVV7G5EI3gYm7Zk3tnu1"; // 你的 Secret Key
aip::Ocr client(app_id, api_key, secret_key); // 新建一个对象, 用于调用接口, 调用通用文字识别, 图片参数为本地图片
// cout << "ok" << endl;
// 定义 json 格式的数据类型 Value, result 是 json 类型的 Value 类实例, 用于存储返回的结果
Json::Value result;
string image; // 用于存储图片内容
// 加载本地的银行卡图片内容到 image 对象中, 用于调用银行卡识别
aip::get_file_content(argv[1], &image);
// 客户端发送图片内容到百度服务器, 并返回结果到 result 对象中
result = client.bankcard(image, aip::null);
int cardTypeNum = result["result"]["bank_card_type"].asInt(); // 卡类型判定 0:不能识别; 1: 借记卡; 2: 信用卡
cout << "识别到的银行卡信息如下: " << endl;
cout << "发卡行: " << result["result"]["bank_name"].asString() << endl;
cout << "卡号: " << result["result"]["bank_card_number"].asString() << endl;
cout << "卡类型: " << cardType(cardTypeNum) << endl;
return 0;
}
// 卡类型判定 0:不能识别; 1: 借记卡; 2: 信用卡
string cardType(int type)
{
switch (type)
{
case 0:
return "不能识别";
case 1:
return "借记卡";
case 2:
return "信用卡";
}
}
+264
View File
@@ -0,0 +1,264 @@
/**
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* @author baidu aip
*/
#ifndef __AIP_BASE_H__
#define __AIP_BASE_H__
#include <memory>
#include <cstring>
#include "http.h"
#include "json/json.h"
#include "base64.h"
#include "curl/curl.h"
#include "utils.h"
namespace aip {
static const char* AIP_SDK_VERSION = "0.3.3";
static const char* CURL_ERROR_CODE = "curl_error_code";
static const std::string ACCESS_TOKEN_URL = "https://aip.baidubce.com/oauth/2.0/token";
static const std::map<std::string, std::string> null;
class AipBase
{
private:
std::string _app_id;
int _expired_time;
bool _is_bce;
bool _has_decide_type;
std::string _scope;
protected:
std::string getAccessToken()
{
time_t now = time(NULL);
if (!access_token.empty())
{
return this->access_token;
}
if (now < this->_expired_time - 60 * 60 * 24)
{
return this->access_token;
}
std::string response;
std::map<std::string, std::string> params;
params["grant_type"] = "client_credentials";
params["client_id"] = this->ak;
params["client_secret"] = this->sk;
int status_code = this->client.get(
ACCESS_TOKEN_URL,
&params,
nullptr,
&response
);
Json::Value obj;
if (status_code != CURLcode::CURLE_OK) {
obj[CURL_ERROR_CODE] = status_code;
return obj.toStyledString();
}
std::string error;
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
this->access_token = obj["access_token"].asString();
this->_expired_time = obj["expires_in"].asInt() + (int) now;
this->_scope = obj["scope"].asString();
return this->access_token;
}
public:
std::string ak;
std::string sk;
HttpClient client;
Json::CharReaderBuilder crbuilder;
std::string access_token;
AipBase(const std::string & app_id, const std::string & ak, const std::string & sk):
_app_id(app_id),
_is_bce(false),
_has_decide_type(false),
ak(ak),
sk(sk)
{
if (_app_id == "")
{
}
}
void setConnectionTimeoutInMillis(int connect_timeout)
{
this->client.setConnectTimeout(connect_timeout);
}
void setSocketTimeoutInMillis(int socket_timeout)
{
this->client.setSocketTimeout(socket_timeout);
}
void setDebug(bool debug)
{
this->client.setDebug(debug);
}
std::string getAk() {
return ak;
}
Json::Value request(
std::string url,
std::map<std::string, std::string> const & params,
std::string const & data,
std::map<std::string, std::string> const & headers)
{
std::string response;
Json::Value obj;
std::string body;
auto headers_for_sign = headers;
auto temp_params = params;
temp_params["charset"] = "UTF-8";
this->prepare_request(url, temp_params, headers_for_sign);
int status_code = this->client.post(url, &temp_params, data, &headers_for_sign, &response);
if (status_code != CURLcode::CURLE_OK) {
obj[CURL_ERROR_CODE] = status_code;
return obj;
}
std::string error;
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
return obj;
}
Json::Value request(
std::string url,
std::map<std::string, std::string> const & params,
std::map<std::string, std::string> const & data,
std::map<std::string, std::string> const & headers)
{
std::string response;
Json::Value obj;
auto headers_for_sign = headers;
auto temp_params = params;
this->prepare_request(url, temp_params, headers_for_sign);
int status_code = this->client.post(url, &temp_params, data, &headers_for_sign, &response);
if (status_code != CURLcode::CURLE_OK) {
obj[CURL_ERROR_CODE] = status_code;
return obj;
}
std::string error;
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
return obj;
}
void prepare_request(std::string url,
std::map<std::string, std::string> & params,
std::map<std::string, std::string> & headers)
{
params["aipSdk"] = "C";
params["aipSdkVersion"] = AIP_SDK_VERSION;
if (_has_decide_type) {
if (_is_bce) {
std::string method = "POST";
sign(method, url, params, headers, ak, sk);
} else {
params["access_token"] = this->getAccessToken();
}
return;
}
if (getAccessToken() == "") {
_is_bce = true;
} else {
const char * t = std::strstr(this->_scope.c_str(), "brain_all_scope");
if (t == NULL)
{
_is_bce = true;
}
}
_has_decide_type = true;
prepare_request(url, params, headers);
}
Json::Value requestjson(
std::string url,
Json::Value & data,
std::map<std::string, std::string> & params,
std::map<std::string, std::string> const & headers)
{
std::string response;
Json::Value obj;
auto headers_for_sign = headers;
auto temp_params = params;
this->prepare_request(url, temp_params, headers_for_sign);
int status_code = this->client.post(url, nullptr, data, nullptr, &response);
if (status_code != CURLcode::CURLE_OK) {
obj[aip::CURL_ERROR_CODE] = status_code;
return obj;
}
std::string error;
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
return obj;
}
Json::Value request_com(
std::string const & url,
Json::Value & data)
{
std::string response;
Json::Value obj;
int status_code = this->client.post(url, nullptr, data, nullptr, &response);
if (status_code != CURLcode::CURLE_OK) {
obj[aip::CURL_ERROR_CODE] = status_code;
return obj;
}
std::string error;
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
return obj;
}
};
}
#endif
+130
View File
@@ -0,0 +1,130 @@
/**
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* @author baidu aip
*/
#ifndef __AIP_BASE64_H__
#define __AIP_BASE64_H__
#include <iostream>
#include <string>
namespace aip {
static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
static inline bool is_base64(const char c)
{
return (isalnum(c) || (c == '+') || (c == '/'));
}
std::string base64_encode(const char * bytes_to_encode, unsigned int in_len)
{
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
while (in_len--)
{
char_array_3[i++] = *(bytes_to_encode++);
if(i == 3)
{
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(i = 0; (i <4) ; i++)
{
ret += base64_chars[char_array_4[i]];
}
i = 0;
}
}
if(i)
{
for(j = i; j < 3; j++)
{
char_array_3[j] = '\0';
}
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(j = 0; (j < i + 1); j++)
{
ret += base64_chars[char_array_4[j]];
}
while((i++ < 3))
{
ret += '=';
}
}
return ret;
}
std::string base64_decode(std::string const & encoded_string)
{
int in_len = (int) encoded_string.size();
int i = 0;
int j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std::string ret;
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_]; in_++;
if (i ==4) {
for (i = 0; i <4; i++)
char_array_4[i] = base64_chars.find(char_array_4[i]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (i = 0; (i < 3); i++)
ret += char_array_3[i];
i = 0;
}
}
if (i) {
for (j = i; j <4; j++)
char_array_4[j] = 0;
for (j = 0; j <4; j++)
char_array_4[j] = base64_chars.find(char_array_4[j]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
}
return ret;
}
}
#endif
+234
View File
@@ -0,0 +1,234 @@
/**
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* @author baidu aip
*/
#ifndef __AIP_HTTP_H__
#define __AIP_HTTP_H__
#include "curl/curl.h"
#include <sstream>
#include <string>
#include <map>
#include <json/json.h>
namespace aip {
inline size_t onWriteData(void * buffer, size_t size, size_t nmemb, void * userp)
{
std::string * str = dynamic_cast<std::string *>((std::string *)userp);
str->append((char *)buffer, size * nmemb);
return nmemb;
}
class HttpClient
{
private:
bool debug = false;
int connect_timeout = 10000;
int socket_timeout = 10000;
void makeUrlencodedForm(std::map<std::string, std::string> const & params, std::string * content) const
{
content->clear();
std::map<std::string, std::string>::const_iterator it;
for(it=params.begin(); it!=params.end(); it++)
{
char * key = curl_escape(it->first.c_str(), (int) it->first.size());
char * value = curl_escape(it->second.c_str(),(int) it->second.size());
*content += key;
*content += '=';
*content += value;
*content += '&';
curl_free(key);
curl_free(value);
}
}
void appendUrlParams(std::map<std::string, std::string> const & params, std::string* url) const
{
if(params.empty()) {
return;
}
std::string content;
this->makeUrlencodedForm(params, &content);
bool url_has_param = false;
for (const auto& ch : *url) {
if (ch == '?') {
url_has_param = true;
break;
}
}
if (url_has_param) {
url->append("&");
} else {
url->append("?");
}
url->append(content);
}
void appendHeaders(std::map<std::string, std::string> const & headers, curl_slist ** slist) const
{
std::ostringstream ostr;
std::map<std::string, std::string>::const_iterator it;
for(it=headers.begin(); it!=headers.end(); it++)
{
ostr << it->first << ":" << it->second;
*slist = curl_slist_append(*slist, ostr.str().c_str());
ostr.str("");
}
}
public:
HttpClient() = default;
HttpClient(const HttpClient &) = delete;
HttpClient & operator=(const HttpClient &) = delete;
void setConnectTimeout(int connect_timeout)
{
this->connect_timeout = connect_timeout;
}
void setSocketTimeout(int socket_timeout)
{
this->socket_timeout = socket_timeout;
}
void setDebug(bool debug)
{
this->debug = debug;
}
int get(
std::string url,
std::map<std::string, std::string> const * params,
std::map<std::string, std::string> const * headers,
std::string * response) const
{
CURL * curl = curl_easy_init();
struct curl_slist * slist = NULL;
if (headers) {
this->appendHeaders(*headers, &slist);
}
if (params) {
this->appendUrlParams(*params, &url);
}
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, onWriteData);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) response);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, true);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, this->connect_timeout);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, this->socket_timeout);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
curl_easy_setopt(curl, CURLOPT_VERBOSE, this->debug);
int status_code = curl_easy_perform(curl);
curl_easy_cleanup(curl);
curl_slist_free_all(slist);
return status_code;
}
int post(
std::string url,
std::map<std::string, std::string> const * params,
const std::string & body,
std::map<std::string, std::string> const * headers,
std::string * response) const
{
struct curl_slist * slist = NULL;
CURL * curl = curl_easy_init();
if (headers) {
this->appendHeaders(*headers, &slist);
}
if (params) {
this->appendUrlParams(*params, &url);
}
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
curl_easy_setopt(curl, CURLOPT_POST, true);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, body.size());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, onWriteData);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) response);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, true);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, this->connect_timeout);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, this->socket_timeout);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
curl_easy_setopt(curl, CURLOPT_VERBOSE, this->debug);
int status_code = curl_easy_perform(curl);
curl_easy_cleanup(curl);
curl_slist_free_all(slist);
return status_code;
}
int post(
std::string url,
std::map<std::string, std::string> const * params,
std::map<std::string, std::string> const & data,
std::map<std::string, std::string> const * headers,
std::string * response) const
{
std::string body;
this->makeUrlencodedForm(data, &body);
return this->post(std::move(url), params, body, headers, response);
}
int post(
std::string url,
std::map<std::string, std::string> const * params,
Json::Value const & data,
std::map<std::string, std::string> const * headers,
std::string * response) const
{
std::string body;
Json::StreamWriterBuilder swb;
std::unique_ptr<Json::StreamWriter> writer(swb.newStreamWriter());
std::ostringstream os;
writer->write(data, &os);
body = os.str();
std::map<std::string, std::string> temp_headers;
if (headers) {
std::map<std::string, std::string> temp_headers(*headers);
}
temp_headers["Content-Type"] = "application/json";
return this->post(url.c_str(), params, body, &temp_headers, response);
}
int post(
std::string url,
std::map<std::string, std::string> const * params,
std::map<std::string, std::string> const * headers,
std::string * response) const
{
const static std::string EMPTY_STRING;
return this->post(std::move(url), params, EMPTY_STRING, headers, response);
}
};
}
#endif
+283
View File
@@ -0,0 +1,283 @@
/**
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* @author baidu aip
*/
#ifndef __AIP_UTILS_H__
#define __AIP_UTILS_H__
#include <string>
#include <fstream>
#include <ctype.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <algorithm>
#include <openssl/md5.h>
const int __BCE_VERSION__ = 1;
const int __BCE_EXPIRE__ = 1800;
namespace aip {
template<class CharT, class Traits, class Allocator>
std::basic_istream<CharT, Traits>& getall(std::basic_istream<CharT, Traits>& input,
std::basic_string<CharT, Traits, Allocator>& str) {
std::ostringstream oss;
oss << input.rdbuf();
str.assign(oss.str());
return input;
}
inline int get_file_content(const char *filename, std::string* out) {
std::ifstream in(filename, std::ios::in | std::ios::binary);
if (in) {
getall(in, *out);
return 0;
} else {
return -1;
}
}
inline std::string to_upper(std::string src)
{
std::transform(src.begin(), src.end(), src.begin(), toupper);
return src;
}
inline std::string to_lower(std::string src)
{
std::transform(src.begin(), src.end(), src.begin(), tolower);
return src;
}
inline std::string to_hex(unsigned char c, bool lower = false)
{
const std::string hex = "0123456789ABCDEF";
std::stringstream ss;
ss << hex[c >> 4] << hex[c & 0xf];
return lower ? to_lower(ss.str()) : ss.str();
}
inline time_t now()
{
return time(NULL);
}
std::string utc_time(time_t timestamp)
{
struct tm result_tm;
char buffer[32];
#ifdef _WIN32
gmtime_s(&result_tm, &timestamp);
#else
gmtime_r(&timestamp, &result_tm);
#endif
size_t size = strftime(buffer, 32, "%Y-%m-%dT%H:%M:%SZ", &result_tm);
return std::string(buffer, size);
}
void url_parse(
const std::string & url,
std::map<std::string, std::string> & params)
{
int pos = (int)url.find("?");
if (pos != -1)
{
int key_start = pos + 1,
key_len = 0,
val_start = 0;
for (int i = key_start; i <= (int)url.size(); ++i)
{
switch (url[i])
{
case '=':
key_len = i - key_start;
val_start = i + 1;
break;
case '\0':
case '&':
if (key_len != 0)
{
params[url.substr(key_start, key_len)] = url.substr(val_start, i - val_start);
key_start = i + 1;
key_len = 0;
}
break;
default:
break;
}
}
}
}
std::string url_encode(const std::string & input, bool encode_slash=true)
{
std::stringstream ss;
const char *str = input.c_str();
for (uint32_t i = 0; i < input.size(); i++)
{
unsigned char c = str[i];
if (isalnum(c) || c == '_' || c == '-' || c == '~' || c == '.' || (!encode_slash && c == '/'))
{
ss << c;
}
else
{
ss << "%" << to_hex(c);
}
}
return ss.str();
}
std::string canonicalize_params(std::map<std::string, std::string> & params)
{
std::vector<std::string> v;
v.reserve(params.size());
for (auto & it : params) {
v.push_back(url_encode(it.first) + "=" + url_encode(it.second));
}
std::sort(v.begin(), v.end());
std::string result;
for (auto & it : v)
{
result.append((result.empty() ? "" : "&") + it);
}
return result;
}
std::string canonicalize_headers(std::map<std::string, std::string> & headers)
{
std::vector<std::string> v;
v.reserve(headers.size());
for (auto & it : headers) {
v.push_back(url_encode(to_lower(it.first)) + ":" + url_encode(it.second));
}
std::sort(v.begin(), v.end());
std::string result;
for (auto & it : v)
{
result.append((result.empty() ? "" : "\n") + it);
}
return result;
}
std::string get_headers_keys(std::map<std::string, std::string> & headers)
{
std::vector<std::string> v;
v.reserve(headers.size());
for (auto & it : headers) {
v.push_back(to_lower(it.first));
}
std::string result;
for (auto & it : v)
{
result.append((result.empty() ? "" : ";") + it);
}
return result;
}
std::string get_host(const std::string & url)
{
int pos = (int)url.find("://") + 3;
return url.substr(
pos,
url.find('/', pos) - pos
);
}
std::string get_path(const std::string & url)
{
int path_start = (int)url.find('/', url.find("://") + 3);
int path_end = (int)url.find('?');
path_end = path_end == -1 ? (int)url.size() : path_end;
return url.substr(path_start, path_end - path_start);
}
std::string hmac_sha256(
const std::string & src,
const std::string & sk)
{
const EVP_MD *evp_md = EVP_sha256();
unsigned char md[EVP_MAX_MD_SIZE];
unsigned int md_len = 0;
if (HMAC(evp_md,
reinterpret_cast<const unsigned char *>(sk.data()), (int)sk.size(),
reinterpret_cast<const unsigned char *>(src.data()), src.size(),
md, &md_len) == NULL)
{
return "";
}
std::stringstream ss;
for (int i = 0; i < (int)md_len; ++i)
{
ss << to_hex(md[i], true);
}
return ss.str();
}
void sign(
std::string method,
std::string & url,
std::map<std::string, std::string> & params,
std::map<std::string, std::string> & headers,
std::string & ak,
std::string & sk)
{
url_parse(url, params);
headers["Host"] = get_host(url);
std::string timestamp = utc_time(now());
headers["x-bce-date"] = timestamp;
std::stringstream ss;
ss << "bce-auth-v" << __BCE_VERSION__ << "/" << ak << "/"
<< timestamp << "/" << __BCE_EXPIRE__;
std::string val = ss.str();
std::string sign_key = hmac_sha256(val, sk);
ss.str("");
ss << to_upper(method) << '\n' << url_encode(get_path(url), false)
<< '\n' << canonicalize_params(params)
<< '\n' << canonicalize_headers(headers);
std::string signature = hmac_sha256(ss.str(), sign_key);
ss.str("");
ss << "bce-auth-v" << __BCE_VERSION__ << "/" << ak << "/"
<< timestamp << "/" << __BCE_EXPIRE__ << "/"
<< get_headers_keys(headers) << "/" << signature;
headers["authorization"] = ss.str();
}
}
#endif
@@ -0,0 +1,44 @@
#include <iostream>
#include "ocr.h" // 用于调用接口
using namespace std;
int main(int argc, char const *argv[])
{
if (argc < 2)
{
cout << "用法: " << argv[0] << " 驾驶证照片" << endl;
return -1;
}
string app_id = "35475147"; // 你的 App ID
string api_key = "CSneGCoRs8zMD1F1PPnXyzPP"; // 你的 Api Key
string secret_key = "wlKjVS2lE9xPFVV7G5EI3gYm7Zk3tnu1"; // 你的 Secret Key
aip::Ocr client(app_id, api_key, secret_key); // 新建一个对象, 用于调用接口, 调用通用文字识别, 图片参数为本地图片
// cout << "ok" << endl;
// 定义 json 格式的数据类型 Value, result 是 json 类型的 Value 类实例, 用于存储返回的结果
Json::Value result;
string image;
// 加载本地的驾驶证图片内容到 image 对象中, 用于调用驾驶证识别
aip::get_file_content(argv[1], &image);
// 客户端发送图片内容到百度服务器, 并返回结果到 result 对象中
result = client.driving_license(image, aip::null);
cout << "识别到的驾驶证信息如下: " << endl;
// cout << result << endl;
cout << "姓名: " << result["words_result"]["姓名"]["words"].asString() << endl;
cout << "出生日期: " << result["words_result"]["出生日期"]["words"].asString() << endl;
cout << "证号: " << result["words_result"]["证号"]["words"].asString() << endl;
cout << "住址: " << result["words_result"]["住址"]["words"].asString() << endl;
cout << "发证单位: " << result["words_result"]["发证单位"]["words"].asString() << endl;
cout << "初次领证日期: " << result["words_result"]["初次领证日期"]["words"].asString() << endl;
cout << "国籍: " << result["words_result"]["国籍"]["words"].asString() << endl;
cout << "准驾车型: " << result["words_result"]["准驾车型"]["words"].asString() << endl;
cout << "性别: " << result["words_result"]["性别"]["words"].asString() << endl;
cout << "有效期限: " << result["words_result"]["有效期限"]["words"].asString() << "" << result["words_result"][""]["words"].asString() << endl;
return 0;
}
+42
View File
@@ -0,0 +1,42 @@
#include <iostream>
#include "ocr.h" // 用于调用接口
using namespace std;
int main(int argc, char const *argv[])
{
if (argc < 2)
{
cout << "用法: " << argv[0] << " 身份证照片" << endl;
return -1;
}
string app_id = "35475147"; // 你的 App ID
string api_key = "CSneGCoRs8zMD1F1PPnXyzPP"; // 你的 Api Key
string secret_key = "wlKjVS2lE9xPFVV7G5EI3gYm7Zk3tnu1"; // 你的 Secret Key
aip::Ocr client(app_id, api_key, secret_key); // 新建一个对象, 用于调用接口, 调用通用文字识别, 图片参数为本地图片
// cout << "ok" << endl;
// 定义 json 格式的数据类型 Value, result 是 json 类型的 Value 类实例, 用于存储返回的结果
Json::Value result;
string image;
// 加载本地的身份证图片内容到 image 对象中, 用于调用身份证识别
aip::get_file_content(argv[1], &image);
// 客户端发送图片内容到百度服务器, 并返回结果到 result 对象中
result = client.idcard(image, "front", aip::null); // front: 正面, back: 背面
cout << "识别到的身份证信息如下: " << endl;
cout << "姓名: " << result["words_result"]["姓名"]["words"].asString() << endl;
cout << "性别: " << result["words_result"]["性别"]["words"].asString() << endl;
cout << "民族: " << result["words_result"]["民族"]["words"].asString() << endl;
cout << "出生: " << result["words_result"]["出生"]["words"].asString() << endl;
cout << "住址: " << result["words_result"]["住址"]["words"].asString() << endl;
cout << "公民身份号码: " << result["words_result"]["公民身份号码"]["words"].asString() << endl;
// cout << "-------------------------" << endl;
// cout << result << endl;
return 0;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

+1551
View File
File diff suppressed because it is too large Load Diff
+17
View File
@@ -0,0 +1,17 @@
cc = g++
cflags = -Wall -lssl -lcrypto -lcurl -ljsoncpp
cflags += -I/home/flykhan/.tools/openssl_build/include/
cflags += -I/home/flykhan/.tools/curl/include/
cflags += -I/home/flykhan/.tools/jsoncpp-Sandbox/jsoncpp-build/include/
cflags += -L/home/flykhan/.tools/openssl_build/lib/
cflags += -L/home/flykhan/.tools/curl/lib/
cflags += -L/home/flykhan/.tools/jsoncpp-Sandbox/jsoncpp-build/lib/
main:
$(cc) main.cpp -o main $(cflags) -std=c++14
jsonTypeShow:
$(cc) jsonTypeShow.cpp -o jsonTypeShow $(cflags) -std=c++14
clean:
rm *.o main jsonTypeShow -rf
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 502 KiB

+264
View File
@@ -0,0 +1,264 @@
/**
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* @author baidu aip
*/
#ifndef __AIP_BASE_H__
#define __AIP_BASE_H__
#include <memory>
#include <cstring>
#include "http.h"
#include "json/json.h"
#include "base64.h"
#include "curl/curl.h"
#include "utils.h"
namespace aip {
static const char* AIP_SDK_VERSION = "0.3.3";
static const char* CURL_ERROR_CODE = "curl_error_code";
static const std::string ACCESS_TOKEN_URL = "https://aip.baidubce.com/oauth/2.0/token";
static const std::map<std::string, std::string> null;
class AipBase
{
private:
std::string _app_id;
int _expired_time;
bool _is_bce;
bool _has_decide_type;
std::string _scope;
protected:
std::string getAccessToken()
{
time_t now = time(NULL);
if (!access_token.empty())
{
return this->access_token;
}
if (now < this->_expired_time - 60 * 60 * 24)
{
return this->access_token;
}
std::string response;
std::map<std::string, std::string> params;
params["grant_type"] = "client_credentials";
params["client_id"] = this->ak;
params["client_secret"] = this->sk;
int status_code = this->client.get(
ACCESS_TOKEN_URL,
&params,
nullptr,
&response
);
Json::Value obj;
if (status_code != CURLcode::CURLE_OK) {
obj[CURL_ERROR_CODE] = status_code;
return obj.toStyledString();
}
std::string error;
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
this->access_token = obj["access_token"].asString();
this->_expired_time = obj["expires_in"].asInt() + (int) now;
this->_scope = obj["scope"].asString();
return this->access_token;
}
public:
std::string ak;
std::string sk;
HttpClient client;
Json::CharReaderBuilder crbuilder;
std::string access_token;
AipBase(const std::string & app_id, const std::string & ak, const std::string & sk):
_app_id(app_id),
_is_bce(false),
_has_decide_type(false),
ak(ak),
sk(sk)
{
if (_app_id == "")
{
}
}
void setConnectionTimeoutInMillis(int connect_timeout)
{
this->client.setConnectTimeout(connect_timeout);
}
void setSocketTimeoutInMillis(int socket_timeout)
{
this->client.setSocketTimeout(socket_timeout);
}
void setDebug(bool debug)
{
this->client.setDebug(debug);
}
std::string getAk() {
return ak;
}
Json::Value request(
std::string url,
std::map<std::string, std::string> const & params,
std::string const & data,
std::map<std::string, std::string> const & headers)
{
std::string response;
Json::Value obj;
std::string body;
auto headers_for_sign = headers;
auto temp_params = params;
temp_params["charset"] = "UTF-8";
this->prepare_request(url, temp_params, headers_for_sign);
int status_code = this->client.post(url, &temp_params, data, &headers_for_sign, &response);
if (status_code != CURLcode::CURLE_OK) {
obj[CURL_ERROR_CODE] = status_code;
return obj;
}
std::string error;
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
return obj;
}
Json::Value request(
std::string url,
std::map<std::string, std::string> const & params,
std::map<std::string, std::string> const & data,
std::map<std::string, std::string> const & headers)
{
std::string response;
Json::Value obj;
auto headers_for_sign = headers;
auto temp_params = params;
this->prepare_request(url, temp_params, headers_for_sign);
int status_code = this->client.post(url, &temp_params, data, &headers_for_sign, &response);
if (status_code != CURLcode::CURLE_OK) {
obj[CURL_ERROR_CODE] = status_code;
return obj;
}
std::string error;
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
return obj;
}
void prepare_request(std::string url,
std::map<std::string, std::string> & params,
std::map<std::string, std::string> & headers)
{
params["aipSdk"] = "C";
params["aipSdkVersion"] = AIP_SDK_VERSION;
if (_has_decide_type) {
if (_is_bce) {
std::string method = "POST";
sign(method, url, params, headers, ak, sk);
} else {
params["access_token"] = this->getAccessToken();
}
return;
}
if (getAccessToken() == "") {
_is_bce = true;
} else {
const char * t = std::strstr(this->_scope.c_str(), "brain_all_scope");
if (t == NULL)
{
_is_bce = true;
}
}
_has_decide_type = true;
prepare_request(url, params, headers);
}
Json::Value requestjson(
std::string url,
Json::Value & data,
std::map<std::string, std::string> & params,
std::map<std::string, std::string> const & headers)
{
std::string response;
Json::Value obj;
auto headers_for_sign = headers;
auto temp_params = params;
this->prepare_request(url, temp_params, headers_for_sign);
int status_code = this->client.post(url, nullptr, data, nullptr, &response);
if (status_code != CURLcode::CURLE_OK) {
obj[aip::CURL_ERROR_CODE] = status_code;
return obj;
}
std::string error;
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
return obj;
}
Json::Value request_com(
std::string const & url,
Json::Value & data)
{
std::string response;
Json::Value obj;
int status_code = this->client.post(url, nullptr, data, nullptr, &response);
if (status_code != CURLcode::CURLE_OK) {
obj[aip::CURL_ERROR_CODE] = status_code;
return obj;
}
std::string error;
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
return obj;
}
};
}
#endif
+130
View File
@@ -0,0 +1,130 @@
/**
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* @author baidu aip
*/
#ifndef __AIP_BASE64_H__
#define __AIP_BASE64_H__
#include <iostream>
#include <string>
namespace aip {
static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
static inline bool is_base64(const char c)
{
return (isalnum(c) || (c == '+') || (c == '/'));
}
std::string base64_encode(const char * bytes_to_encode, unsigned int in_len)
{
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
while (in_len--)
{
char_array_3[i++] = *(bytes_to_encode++);
if(i == 3)
{
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(i = 0; (i <4) ; i++)
{
ret += base64_chars[char_array_4[i]];
}
i = 0;
}
}
if(i)
{
for(j = i; j < 3; j++)
{
char_array_3[j] = '\0';
}
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(j = 0; (j < i + 1); j++)
{
ret += base64_chars[char_array_4[j]];
}
while((i++ < 3))
{
ret += '=';
}
}
return ret;
}
std::string base64_decode(std::string const & encoded_string)
{
int in_len = (int) encoded_string.size();
int i = 0;
int j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std::string ret;
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_]; in_++;
if (i ==4) {
for (i = 0; i <4; i++)
char_array_4[i] = base64_chars.find(char_array_4[i]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (i = 0; (i < 3); i++)
ret += char_array_3[i];
i = 0;
}
}
if (i) {
for (j = i; j <4; j++)
char_array_4[j] = 0;
for (j = 0; j <4; j++)
char_array_4[j] = base64_chars.find(char_array_4[j]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
}
return ret;
}
}
#endif
+234
View File
@@ -0,0 +1,234 @@
/**
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* @author baidu aip
*/
#ifndef __AIP_HTTP_H__
#define __AIP_HTTP_H__
#include "curl/curl.h"
#include <sstream>
#include <string>
#include <map>
#include <json/json.h>
namespace aip {
inline size_t onWriteData(void * buffer, size_t size, size_t nmemb, void * userp)
{
std::string * str = dynamic_cast<std::string *>((std::string *)userp);
str->append((char *)buffer, size * nmemb);
return nmemb;
}
class HttpClient
{
private:
bool debug = false;
int connect_timeout = 10000;
int socket_timeout = 10000;
void makeUrlencodedForm(std::map<std::string, std::string> const & params, std::string * content) const
{
content->clear();
std::map<std::string, std::string>::const_iterator it;
for(it=params.begin(); it!=params.end(); it++)
{
char * key = curl_escape(it->first.c_str(), (int) it->first.size());
char * value = curl_escape(it->second.c_str(),(int) it->second.size());
*content += key;
*content += '=';
*content += value;
*content += '&';
curl_free(key);
curl_free(value);
}
}
void appendUrlParams(std::map<std::string, std::string> const & params, std::string* url) const
{
if(params.empty()) {
return;
}
std::string content;
this->makeUrlencodedForm(params, &content);
bool url_has_param = false;
for (const auto& ch : *url) {
if (ch == '?') {
url_has_param = true;
break;
}
}
if (url_has_param) {
url->append("&");
} else {
url->append("?");
}
url->append(content);
}
void appendHeaders(std::map<std::string, std::string> const & headers, curl_slist ** slist) const
{
std::ostringstream ostr;
std::map<std::string, std::string>::const_iterator it;
for(it=headers.begin(); it!=headers.end(); it++)
{
ostr << it->first << ":" << it->second;
*slist = curl_slist_append(*slist, ostr.str().c_str());
ostr.str("");
}
}
public:
HttpClient() = default;
HttpClient(const HttpClient &) = delete;
HttpClient & operator=(const HttpClient &) = delete;
void setConnectTimeout(int connect_timeout)
{
this->connect_timeout = connect_timeout;
}
void setSocketTimeout(int socket_timeout)
{
this->socket_timeout = socket_timeout;
}
void setDebug(bool debug)
{
this->debug = debug;
}
int get(
std::string url,
std::map<std::string, std::string> const * params,
std::map<std::string, std::string> const * headers,
std::string * response) const
{
CURL * curl = curl_easy_init();
struct curl_slist * slist = NULL;
if (headers) {
this->appendHeaders(*headers, &slist);
}
if (params) {
this->appendUrlParams(*params, &url);
}
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, onWriteData);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) response);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, true);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, this->connect_timeout);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, this->socket_timeout);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
curl_easy_setopt(curl, CURLOPT_VERBOSE, this->debug);
int status_code = curl_easy_perform(curl);
curl_easy_cleanup(curl);
curl_slist_free_all(slist);
return status_code;
}
int post(
std::string url,
std::map<std::string, std::string> const * params,
const std::string & body,
std::map<std::string, std::string> const * headers,
std::string * response) const
{
struct curl_slist * slist = NULL;
CURL * curl = curl_easy_init();
if (headers) {
this->appendHeaders(*headers, &slist);
}
if (params) {
this->appendUrlParams(*params, &url);
}
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
curl_easy_setopt(curl, CURLOPT_POST, true);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, body.size());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, onWriteData);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) response);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, true);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, this->connect_timeout);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, this->socket_timeout);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
curl_easy_setopt(curl, CURLOPT_VERBOSE, this->debug);
int status_code = curl_easy_perform(curl);
curl_easy_cleanup(curl);
curl_slist_free_all(slist);
return status_code;
}
int post(
std::string url,
std::map<std::string, std::string> const * params,
std::map<std::string, std::string> const & data,
std::map<std::string, std::string> const * headers,
std::string * response) const
{
std::string body;
this->makeUrlencodedForm(data, &body);
return this->post(std::move(url), params, body, headers, response);
}
int post(
std::string url,
std::map<std::string, std::string> const * params,
Json::Value const & data,
std::map<std::string, std::string> const * headers,
std::string * response) const
{
std::string body;
Json::StreamWriterBuilder swb;
std::unique_ptr<Json::StreamWriter> writer(swb.newStreamWriter());
std::ostringstream os;
writer->write(data, &os);
body = os.str();
std::map<std::string, std::string> temp_headers;
if (headers) {
std::map<std::string, std::string> temp_headers(*headers);
}
temp_headers["Content-Type"] = "application/json";
return this->post(url.c_str(), params, body, &temp_headers, response);
}
int post(
std::string url,
std::map<std::string, std::string> const * params,
std::map<std::string, std::string> const * headers,
std::string * response) const
{
const static std::string EMPTY_STRING;
return this->post(std::move(url), params, EMPTY_STRING, headers, response);
}
};
}
#endif
+283
View File
@@ -0,0 +1,283 @@
/**
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* @author baidu aip
*/
#ifndef __AIP_UTILS_H__
#define __AIP_UTILS_H__
#include <string>
#include <fstream>
#include <ctype.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <algorithm>
#include <openssl/md5.h>
const int __BCE_VERSION__ = 1;
const int __BCE_EXPIRE__ = 1800;
namespace aip {
template<class CharT, class Traits, class Allocator>
std::basic_istream<CharT, Traits>& getall(std::basic_istream<CharT, Traits>& input,
std::basic_string<CharT, Traits, Allocator>& str) {
std::ostringstream oss;
oss << input.rdbuf();
str.assign(oss.str());
return input;
}
inline int get_file_content(const char *filename, std::string* out) {
std::ifstream in(filename, std::ios::in | std::ios::binary);
if (in) {
getall(in, *out);
return 0;
} else {
return -1;
}
}
inline std::string to_upper(std::string src)
{
std::transform(src.begin(), src.end(), src.begin(), toupper);
return src;
}
inline std::string to_lower(std::string src)
{
std::transform(src.begin(), src.end(), src.begin(), tolower);
return src;
}
inline std::string to_hex(unsigned char c, bool lower = false)
{
const std::string hex = "0123456789ABCDEF";
std::stringstream ss;
ss << hex[c >> 4] << hex[c & 0xf];
return lower ? to_lower(ss.str()) : ss.str();
}
inline time_t now()
{
return time(NULL);
}
std::string utc_time(time_t timestamp)
{
struct tm result_tm;
char buffer[32];
#ifdef _WIN32
gmtime_s(&result_tm, &timestamp);
#else
gmtime_r(&timestamp, &result_tm);
#endif
size_t size = strftime(buffer, 32, "%Y-%m-%dT%H:%M:%SZ", &result_tm);
return std::string(buffer, size);
}
void url_parse(
const std::string & url,
std::map<std::string, std::string> & params)
{
int pos = (int)url.find("?");
if (pos != -1)
{
int key_start = pos + 1,
key_len = 0,
val_start = 0;
for (int i = key_start; i <= (int)url.size(); ++i)
{
switch (url[i])
{
case '=':
key_len = i - key_start;
val_start = i + 1;
break;
case '\0':
case '&':
if (key_len != 0)
{
params[url.substr(key_start, key_len)] = url.substr(val_start, i - val_start);
key_start = i + 1;
key_len = 0;
}
break;
default:
break;
}
}
}
}
std::string url_encode(const std::string & input, bool encode_slash=true)
{
std::stringstream ss;
const char *str = input.c_str();
for (uint32_t i = 0; i < input.size(); i++)
{
unsigned char c = str[i];
if (isalnum(c) || c == '_' || c == '-' || c == '~' || c == '.' || (!encode_slash && c == '/'))
{
ss << c;
}
else
{
ss << "%" << to_hex(c);
}
}
return ss.str();
}
std::string canonicalize_params(std::map<std::string, std::string> & params)
{
std::vector<std::string> v;
v.reserve(params.size());
for (auto & it : params) {
v.push_back(url_encode(it.first) + "=" + url_encode(it.second));
}
std::sort(v.begin(), v.end());
std::string result;
for (auto & it : v)
{
result.append((result.empty() ? "" : "&") + it);
}
return result;
}
std::string canonicalize_headers(std::map<std::string, std::string> & headers)
{
std::vector<std::string> v;
v.reserve(headers.size());
for (auto & it : headers) {
v.push_back(url_encode(to_lower(it.first)) + ":" + url_encode(it.second));
}
std::sort(v.begin(), v.end());
std::string result;
for (auto & it : v)
{
result.append((result.empty() ? "" : "\n") + it);
}
return result;
}
std::string get_headers_keys(std::map<std::string, std::string> & headers)
{
std::vector<std::string> v;
v.reserve(headers.size());
for (auto & it : headers) {
v.push_back(to_lower(it.first));
}
std::string result;
for (auto & it : v)
{
result.append((result.empty() ? "" : ";") + it);
}
return result;
}
std::string get_host(const std::string & url)
{
int pos = (int)url.find("://") + 3;
return url.substr(
pos,
url.find('/', pos) - pos
);
}
std::string get_path(const std::string & url)
{
int path_start = (int)url.find('/', url.find("://") + 3);
int path_end = (int)url.find('?');
path_end = path_end == -1 ? (int)url.size() : path_end;
return url.substr(path_start, path_end - path_start);
}
std::string hmac_sha256(
const std::string & src,
const std::string & sk)
{
const EVP_MD *evp_md = EVP_sha256();
unsigned char md[EVP_MAX_MD_SIZE];
unsigned int md_len = 0;
if (HMAC(evp_md,
reinterpret_cast<const unsigned char *>(sk.data()), (int)sk.size(),
reinterpret_cast<const unsigned char *>(src.data()), src.size(),
md, &md_len) == NULL)
{
return "";
}
std::stringstream ss;
for (int i = 0; i < (int)md_len; ++i)
{
ss << to_hex(md[i], true);
}
return ss.str();
}
void sign(
std::string method,
std::string & url,
std::map<std::string, std::string> & params,
std::map<std::string, std::string> & headers,
std::string & ak,
std::string & sk)
{
url_parse(url, params);
headers["Host"] = get_host(url);
std::string timestamp = utc_time(now());
headers["x-bce-date"] = timestamp;
std::stringstream ss;
ss << "bce-auth-v" << __BCE_VERSION__ << "/" << ak << "/"
<< timestamp << "/" << __BCE_EXPIRE__;
std::string val = ss.str();
std::string sign_key = hmac_sha256(val, sk);
ss.str("");
ss << to_upper(method) << '\n' << url_encode(get_path(url), false)
<< '\n' << canonicalize_params(params)
<< '\n' << canonicalize_headers(headers);
std::string signature = hmac_sha256(ss.str(), sign_key);
ss.str("");
ss << "bce-auth-v" << __BCE_VERSION__ << "/" << ak << "/"
<< timestamp << "/" << __BCE_EXPIRE__ << "/"
<< get_headers_keys(headers) << "/" << signature;
headers["authorization"] = ss.str();
}
}
#endif
+77
View File
@@ -0,0 +1,77 @@
#include <iostream>
#include "ocr.h" // 用于调用接口
#include <string> // 用于 string 的操作
#include <codecvt> // 用于转码
using namespace std;
const static string request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/license_plate";
static string result;
int lincesePlate(string &token, const char *image_path);
int callback(char *, size_t, size_t, void *);
int main(int argc, char const *argv[]) // argc: 参数个数, argv: 参数列表
{
if (argc < 2)
{
cout << "用法: " << argv[0] << " 车牌图片路径" << endl;
return 1; // 返回 1 表示失败
}
string token = "24.1509bd6033f9988f4e0f289b625dc0c8.2592000.1690601100.282335-35458273";
lincesePlate(token, argv[1]);
return 0;
}
int lincesePlate(string &token, const char *image_path)
{
// HTTP 请求的完整 URL 路径
string url = request_url + "?access_token=" + token;
CURL *curl; // 定义一个指向CURL类型的指针
CURLcode code; // 定义一个CURLcode类型的变量, 用于接收返回状态码
curl = curl_easy_init(); // 初始化一个CURL类型的指针
if (curl)
{
// 设置请求的 URL 地址
curl_easy_setopt(curl, CURLOPT_URL, url.data()); // url.data() 等于 url.c_str(), 返回一个指向正规 C 字符串的指针常量, 即返回一个指向以空字符终止的字符数组的指针
curl_easy_setopt(curl, CURLOPT_POST, 1); // 设置为非 0, 表示本次操作为 POST
string image;
aip::get_file_content(image_path, &image); // 读取图片文件
string img_base64 = aip::base64_encode(image.c_str(), image.length()); // 将图片文件转为 base64 编码, image.c_str(): 返回指向正规 C 字符串的指针常量, 即返回一个指向以空字符终止的字符数组的指针, image.length(): 返回字符串的长度
curl_httppost *post, *last; // *post: 指向第一个元素的指针, *last: 指向最后一个元素的指针
// 以表单的方式上传 image 字段的数据
curl_formadd(&post, &last, CURLFORM_COPYNAME, "image", CURLFORM_COPYCONTENTS, img_base64.data(), CURLFORM_END); // 参数说明: &post: 指向第一个元素的指针, &last: 指向最后一个元素的指针, CURLFORM_COPYNAME: 指定表单的字段名, CURLFORM_COPYCONTENTS: 指定表单字段的值, CURLFORM_END: 用于结束整个表单
curl_easy_setopt(curl, CURLOPT_HTTPPOST, post); // 设置表单字段和值
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback); // 设置回调函数
code = curl_easy_perform(curl); // 执行请求, 该函数完成后, 错误码将会写入 code 变量
cout << code << endl; // 打印结果
curl_easy_cleanup(curl); // 清除 curl 操作, 即结束本次请求
return 0; // 返回 0 表示成功
}
fprintf(stderr, "curl init failed!\n"); // 如果返回非 0, 则表示失败
return 1; // 返回 1 表示失败
}
int callback(char *buffer, size_t size, size_t nitems, void *outstream)
{
result = string(buffer, size * nitems); // 将 buffer 中的数据拷贝到 result 中
// 将 result 数据转化为 json 格式
Json::Reader json_type_result; // 定义一个 json 格式的变量
string error; // 定义一个 string 类型的变量, 用于接收错误信息
Json::CharReaderBuilder crbuilder; // CharReaderBuilder 类提供了一个简单的 API 来从字符流读取 JSON 文档
unique_ptr<Json::CharReader> reader(crbuilder.newCharReader()); // unique_ptr: 一个独占的指针, 用于管理另一个对象的生命周期, 该对象使用 delete 销毁
reader->parse(result.c_str(), result.c_str() + result.length(), &json_type_result, &error); // 将 result 转化为 json 格式
cout << result << endl; // 打印结果
return 0;
}
BIN
View File
Binary file not shown.
+69
View File
@@ -0,0 +1,69 @@
#include <iostream>
#include "ocr.h" // 用于调用接口
#include <string> // 用于 string 的操作
#include <codecvt> // 用于转码
using namespace std;
const static string request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/license_plate";
static string result;
int lincesePlate(string &token, const char *image_path);
int callback(char *, size_t, size_t, void *);
int main(int argc, char const *argv[]) // argc: 参数个数, argv: 参数列表
{
if (argc < 2)
{
cout << "用法: " << argv[0] << " 车牌图片路径" << endl;
return 1; // 返回 1 表示失败
}
string token = "24.1509bd6033f9988f4e0f289b625dc0c8.2592000.1690601100.282335-35458273";
lincesePlate(token, argv[1]);
return 0;
}
int lincesePlate(string &token, const char *image_path)
{
// HTTP 请求的完整 URL 路径
string url = request_url + "?access_token=" + token;
CURL *curl; // 定义一个指向CURL类型的指针
CURLcode code; // 定义一个CURLcode类型的变量, 用于接收返回状态码
curl = curl_easy_init(); // 初始化一个CURL类型的指针
if (curl)
{
// 设置请求的 URL 地址
curl_easy_setopt(curl, CURLOPT_URL, url.data()); // url.data() 等于 url.c_str(), 返回一个指向正规 C 字符串的指针常量, 即返回一个指向以空字符终止的字符数组的指针
curl_easy_setopt(curl, CURLOPT_POST, 1); // 设置为非 0, 表示本次操作为 POST
string image;
aip::get_file_content(image_path, &image); // 读取图片文件
string img_base64 = aip::base64_encode(image.c_str(), image.length()); // 将图片文件转为 base64 编码, image.c_str(): 返回指向正规 C 字符串的指针常量, 即返回一个指向以空字符终止的字符数组的指针, image.length(): 返回字符串的长度
curl_httppost *post, *last; // *post: 指向第一个元素的指针, *last: 指向最后一个元素的指针
// 以表单的方式上传 image 字段的数据
curl_formadd(&post, &last, CURLFORM_COPYNAME, "image", CURLFORM_COPYCONTENTS, img_base64.data(), CURLFORM_END); // 参数说明: &post: 指向第一个元素的指针, &last: 指向最后一个元素的指针, CURLFORM_COPYNAME: 指定表单的字段名, CURLFORM_COPYCONTENTS: 指定表单字段的值, CURLFORM_END: 用于结束整个表单
curl_easy_setopt(curl, CURLOPT_HTTPPOST, post); // 设置表单字段和值
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback); // 设置回调函数
code = curl_easy_perform(curl); // 执行请求, 该函数完成后, 错误码将会写入 code 变量
cout << code << endl; // 打印结果
curl_easy_cleanup(curl); // 清除 curl 操作, 即结束本次请求
return 0; // 返回 0 表示成功
}
fprintf(stderr, "curl init failed!\n"); // 如果返回非 0, 则表示失败
return 1; // 返回 1 表示失败
}
int callback(char *buffer, size_t size, size_t nitems, void *outstream)
{
result = string(buffer, size * nitems); // 将 buffer 中的数据拷贝到 result 中
cout << result << endl; // 打印结果
return 0;
}
+1551
View File
File diff suppressed because it is too large Load Diff
+19
View File
@@ -0,0 +1,19 @@
// 打印九九乘法表
#include <iostream>
using namespace std;
int main()
{
for (int i = 1; i < 10; i++)
{
for (int j = 1; j < 10; j++)
{
if (j <= i)
cout << i << "*" << j << "=" << i * j << "\t";
}
cout << endl;
}
return 0;
}
+23
View File
@@ -0,0 +1,23 @@
// 源码反码补码
#include <iostream>
#include <bitset>
using namespace std;
int main()
{
int z = -9;
cout << bitset<8>(z) << endl;
cout << bitset<8>(z >> 1) << endl; // 右移一位,符号位不变,左边补1
cout << bitset<8>(z << 1) << endl; // 左移一位,符号位不变,右边补0
cout << dec << z << endl; // 十进制
cout << oct << z << endl; // 八进制
cout << hex << z << endl; // 十六进制
signed int x = 20;
cout << bitset<8>(x) << endl;
cout << bitset<8>(x >> 1) << endl; // 右移一位,符号位不变,左边补0
cout << bitset<8>(x << 1) << endl; // 左移一位,符号位不变,右边补0
return 0;
}
+14
View File
@@ -0,0 +1,14 @@
// 无符号数
#include <iostream>
#include <bitset>
using namespace std;
int main()
{
unsigned char a = 255, b = 0, c = 0x30;
cout << bitset<8>(a) << "," << dec << (int)a << endl;
cout << bitset<8>(b) << "," << dec << (int)b << endl;
cout << bitset<8>(c) << "," << dec << (int)c << endl;
return 0;
}
+12
View File
@@ -0,0 +1,12 @@
// 进制转换
#include <iostream>
using namespace std;
int main()
{
int n1 = 037, n2 = 0x3a;
cout << "037 = " << n1 << endl; // 以10进制输出八进制数
cout << "0x3a = " << n2 << endl; // 以10进制输出十六进制数
return 0;
}
+12
View File
@@ -0,0 +1,12 @@
// 测试负数的二进制表示:补码方式存储
#include <iostream>
#include <bitset>
using namespace std;
int main()
{
int x = -123;
cout << bitset<8>(x) << endl;
return 0;
}
+25
View File
@@ -0,0 +1,25 @@
// sizeof测试
#include <iostream>
using namespace std;
int main()
{
char c = 'a';
cout << c << endl;
cout << sizeof(c) << endl;
short x = '1';
cout << x << endl;
cout << sizeof(x) << endl;
int z = 1;
cout << z << endl;
cout << sizeof(z) << endl;
bool y = true;
cout << y << endl;
cout << sizeof(y) << endl;
return 0;
}
+16
View File
@@ -0,0 +1,16 @@
// 测试一个整数能否被3整除
#include <iostream>
using namespace std;
int main()
{
unsigned int n;
cout << "请输入一个整数:";
cin >> n;
if (n % 3 == 0)
cout << "能被3整除" << endl;
else
cout << "不能被3整除" << endl;
return 0;
}
+20
View File
@@ -0,0 +1,20 @@
// 测试随机数
#include <iostream>
#include <cstdlib> // C++兼容C语言的标准库
#include <ctime> // C++兼容C语言的时间库
using namespace std;
// stand(数值) 设置随机数种子, 一般使用 time(NULL) 获取当前时间 (相对于1970年1月1日的秒数) 作为随机数种子
// rand() 生成 0 ~ RAND_MAX 之间的随机数
// 如果随机产生 (min, max) 区间的随机数, 可以使用 rand() % (max - min + 1) + min
int main()
{
// 将当前时间作为随机数种子 (作用: 不同时间产生的随机数不同)
srand(time(NULL)); // 设置随机数种子
// 生成 60~100 之间的随机数
int num = rand() % 41 + 60;
cout << num << endl;
return 0;
}
+20
View File
@@ -0,0 +1,20 @@
// 测试生成a-z之间的随机字符
#include <iostream>
#include <cstdlib> // C++兼容C语言的标准库
#include <ctime> // C++兼容C语言的时间库
using namespace std;
// stand(数值) 设置随机数种子, 一般使用 time(NULL) 获取当前时间 (相对于1970年1月1日的秒数) 作为随机数种子
// rand() 生成 0 ~ RAND_MAX 之间的随机数
// 如果随机产生 (min, max) 区间的随机数, 可以使用 rand() % (max - min + 1) + min
int main()
{
// 将当前时间作为随机数种子 (作用: 不同时间产生的随机数不同)
srand(time(NULL)); // 设置随机数种子
// 生成 a~z 之间的随机字符
int num = rand() % 27 + 97;
cout << (char)num << endl;
return 0;
}
+16
View File
@@ -0,0 +1,16 @@
// 测试goto语句
#include <iostream>
using namespace std;
int main()
{
cout << "1" <<endl;
cout << "2" <<endl;
goto FLAG;
cout << "3" <<endl;
cout << "4" <<endl;
FLAG:
cout << "5" <<endl;
return 0;
}

Some files were not shown because too many files have changed in this diff Show More