Qt(C++)調(diào)用工業(yè)相機(jī)Basler的SDK使用示例
簡(jiǎn)介
由于公司采購(gòu)的AVT相機(jī)不足,需要用Basler相機(jī)來(lái)彌補(bǔ),所以我也了解了一下Basler這款相機(jī)的SDK。由于Basler這邊的相機(jī)提供的沒(méi)有提供Qt的示例,所以我做一個(gè)分享出來(lái)。
本篇的Demo采用的是工業(yè)黑白相機(jī)。工業(yè)應(yīng)用中,如果我們要處理的是與圖像顏色有關(guān),那么我們最好采用彩色工業(yè)相機(jī);如果不是,那么我們最好選用黑白工業(yè)相機(jī),因?yàn)樵谕瑯臃直媛氏碌墓I(yè)相機(jī),黑白工業(yè)教學(xué)精度比彩色工業(yè)相機(jī)高,尤其是在看圖像邊緣的時(shí)候,黑白工業(yè)相機(jī)的效果更好。
開(kāi)發(fā)環(huán)境
- Qt: 5.6.2vc2013版
- Basler: 5.0.11版
效果圖
上圖只是做了SDK部分接口的獲取和設(shè)置。相機(jī)的觸發(fā)方式、曝光時(shí)間、增益、頻率,以及圖片的尺寸、燈的觸發(fā)信號(hào)等。
Basler相機(jī)SDK接口調(diào)用控制類(lèi)
#ifndef SBASLERCAMERACONTROL_H #define SBASLERCAMERACONTROL_H #include <QObject> #include <pylon/PylonIncludes.h> #include <QImage> #include <QTimer> #define DOUBLE_MAX 100000 #define DOUBLE_MIN 0 using namespace std; using namespace Pylon; using namespace GenApi; class SBaslerCameraControl : public QObject { Q_OBJECT public: explicit SBaslerCameraControl(QObject *parent = 0); ~SBaslerCameraControl(); enum SBaslerCameraControl_Type{ Type_Basler_Freerun, //設(shè)置相機(jī)的內(nèi)觸發(fā) Type_Basler_Line1, //設(shè)置相機(jī)的外觸發(fā) Type_Basler_ExposureTimeAbs, //設(shè)置相機(jī)的曝光時(shí)間 Type_Basler_GainRaw, //設(shè)置相機(jī)的增益 Type_Basler_AcquisitionFrameRateAbs, //設(shè)置相機(jī)的頻率 Type_Basler_Width, //圖片的寬度 Type_Basler_Height, //圖片的高度 Type_Basler_LineSource, //燈的觸發(fā)信號(hào) }; void initSome(); void deleteAll(); QStringList cameras(); int OpenCamera(QString cameraSN); int CloseCamera(); void setExposureTime(double time); // 設(shè)置曝光時(shí)間 int getExposureTime(); // 獲取曝光時(shí)間 int getExposureTimeMin(); // 最小曝光時(shí)間 int getExposureTimeMax(); // 最大曝光時(shí)間 void setFeatureTriggerSourceType(QString type); // 設(shè)置種類(lèi) QString getFeatureTriggerSourceType(); // 獲取種類(lèi):軟觸發(fā)、外觸發(fā)等等 void setFeatureTriggerModeType(bool on); // 設(shè)置模式觸發(fā) bool getFeatureTriggerModeType(); // 獲取模式觸發(fā) void SetCamera(SBaslerCameraControl::SBaslerCameraControl_Type index, double tmpValue = 0.0); // 設(shè)置各種參數(shù) double GetCamera(SBaslerCameraControl::SBaslerCameraControl_Type index); // 獲取各種參數(shù) long GrabImage(QImage& image,int timeout = 2000); long StartAcquire(); // 開(kāi)始采集 long StopAcquire(); // 結(jié)束采集 signals: void sigCameraUpdate(QStringList list); void sigSizeChange(QSize size); void sigCameraCount(int count); void sigCurrentImage(QImage img); private: void UpdateCameraList(); void CopyToImage(CGrabResultPtr pInBuffer, QImage &OutImage); private slots: void onTimerGrabImage(); private: CInstantCamera m_basler; QStringList m_cameralist; QString m_currentMode; bool m_isOpenAcquire = false; // 是否開(kāi)始采集 bool m_isOpen = false; // 是否打開(kāi)攝像頭 QSize m_size; }; #endif // SBASLERCAMERACONTROL_H
源文件:
#include "sbaslercameracontrol.h" #include <QDateTime> #include <QDebug> SBaslerCameraControl::SBaslerCameraControl(QObject *parent) : QObject(parent) { } SBaslerCameraControl::~SBaslerCameraControl() { } void SBaslerCameraControl::initSome() { qDebug() << "SBaslerCameraControl: PylonInitialize initSome" ; PylonInitialize(); CTlFactory &TlFactory = CTlFactory::GetInstance(); TlInfoList_t lstInfo; int n = TlFactory.EnumerateTls(lstInfo); TlInfoList_t::const_iterator it; for ( it = lstInfo.begin(); it != lstInfo.end(); ++it ) { qDebug() << "FriendlyName: " << it->GetFriendlyName() << "FullName: " << it->GetFullName(); qDebug() << "VendorName: " << it->GetVendorName() << "DeviceClass: " << it->GetDeviceClass() ; } UpdateCameraList(); emit sigCameraCount(n); qDebug() << "SBasler Camera Count: " << n; } void SBaslerCameraControl::deleteAll() { //停止采集 if(m_isOpenAcquire) { StopAcquire(); } //關(guān)閉攝像頭 CloseCamera(); //關(guān)閉庫(kù) qDebug() << "SBaslerCameraControl deleteAll: PylonTerminate" ; PylonTerminate(); qDebug() << "SBaslerCameraControl deleteAll: Close" ; } QStringList SBaslerCameraControl::cameras() { return m_cameralist; } void SBaslerCameraControl::UpdateCameraList() { CTlFactory& TLFactory = CTlFactory::GetInstance(); ITransportLayer * pTl = TLFactory.CreateTl("BaslerGigE"); DeviceInfoList_t devices; int n = pTl->EnumerateDevices(devices); CInstantCameraArray cameraArray(devices.size()); if(n == 0) { qDebug() << "Cannot find Any camera!"; return; } for (int i=0 ; i<cameraArray.GetSize() ; i++) { cameraArray[i].Attach(TLFactory.CreateDevice(devices[i])); string sn = cameraArray[i].GetDeviceInfo().GetSerialNumber(); m_cameralist << QString::fromStdString(sn); } emit sigCameraUpdate(m_cameralist); } void SBaslerCameraControl::CopyToImage(CGrabResultPtr pInBuffer, QImage &OutImage) { uchar* buff = (uchar*)pInBuffer->GetBuffer(); int nHeight = pInBuffer->GetHeight(); int nWidth = pInBuffer->GetWidth(); if(m_size != QSize(nWidth, nHeight)) { m_size = QSize(nWidth, nHeight); emit sigSizeChange(m_size); } QImage imgBuff(buff, nWidth, nHeight, QImage::Format_Indexed8); OutImage = imgBuff; if(pInBuffer->GetPixelType() == PixelType_Mono8) { uchar* pCursor = OutImage.bits(); if ( OutImage.bytesPerLine() != nWidth ) { for ( int y=0; y<nHeight; ++y ) { pCursor = OutImage.scanLine( y ); for ( int x=0; x<nWidth; ++x ) { *pCursor =* buff; ++pCursor; ++buff; } } } else { memcpy( OutImage.bits(), buff, nWidth * nHeight ); } } } void SBaslerCameraControl::onTimerGrabImage() { if(m_isOpenAcquire) { QImage image; GrabImage(image, 5); if(!image.isNull()) { emit sigCurrentImage(image); } QTimer::singleShot(5, this, SLOT(onTimerGrabImage())); } } int SBaslerCameraControl::OpenCamera(QString cameraSN) { try { CDeviceInfo cInfo; String_t str = String_t(cameraSN.toStdString().c_str()); cInfo.SetSerialNumber(str); m_basler.Attach(CTlFactory::GetInstance().CreateDevice(cInfo)); m_basler.Open(); //獲取觸發(fā)模式 getFeatureTriggerSourceType(); m_isOpen = true; } catch (GenICam::GenericException &e) { OutputDebugString(L"OpenCamera Error\n"); m_isOpen = false; return -2; } return 0; } int SBaslerCameraControl::CloseCamera() { if(!m_isOpen) { return -1; } try { if(m_basler.IsOpen()) { m_basler.DetachDevice(); m_basler.Close(); } } catch (GenICam::GenericException &e) { OutputDebugString(LPCWSTR(e.GetDescription())); return -2; } return 0; } void SBaslerCameraControl::setExposureTime(double time) { SetCamera(Type_Basler_ExposureTimeAbs, time); } int SBaslerCameraControl::getExposureTime() { return QString::number(GetCamera(Type_Basler_ExposureTimeAbs)).toInt(); } int SBaslerCameraControl::getExposureTimeMin() { return DOUBLE_MIN; } int SBaslerCameraControl::getExposureTimeMax() { return DOUBLE_MAX; } void SBaslerCameraControl::setFeatureTriggerSourceType(QString type) { //停止采集 if(m_isOpenAcquire) { StopAcquire(); } if(type == "Freerun") { SetCamera(Type_Basler_Freerun); } else if(type == "Line1"){ SetCamera(Type_Basler_Line1); } } QString SBaslerCameraControl::getFeatureTriggerSourceType() { INodeMap &cameraNodeMap = m_basler.GetNodeMap(); CEnumerationPtr ptrTriggerSel = cameraNodeMap.GetNode ("TriggerSelector"); ptrTriggerSel->FromString("FrameStart"); CEnumerationPtr ptrTrigger = cameraNodeMap.GetNode ("TriggerMode"); ptrTrigger->SetIntValue(1); CEnumerationPtr ptrTriggerSource = cameraNodeMap.GetNode ("TriggerSource"); String_t str = ptrTriggerSource->ToString(); m_currentMode = QString::fromLocal8Bit(str.c_str()); return m_currentMode; } void SBaslerCameraControl::setFeatureTriggerModeType(bool on) { INodeMap &cameraNodeMap = m_basler.GetNodeMap(); CEnumerationPtr ptrTriggerSel = cameraNodeMap.GetNode ("TriggerSelector"); ptrTriggerSel->FromString("FrameStart"); CEnumerationPtr ptrTrigger = cameraNodeMap.GetNode ("TriggerMode"); ptrTrigger->SetIntValue(on?1:0); } bool SBaslerCameraControl::getFeatureTriggerModeType() { INodeMap &cameraNodeMap = m_basler.GetNodeMap(); CEnumerationPtr ptrTriggerSel = cameraNodeMap.GetNode ("TriggerSelector"); ptrTriggerSel->FromString("FrameStart"); CEnumerationPtr ptrTrigger = cameraNodeMap.GetNode ("TriggerMode"); return ptrTrigger->GetIntValue() == 1; } void SBaslerCameraControl::SetCamera(SBaslerCameraControl::SBaslerCameraControl_Type index, double tmpValue) { INodeMap &cameraNodeMap = m_basler.GetNodeMap(); switch (index) { case Type_Basler_Freerun: { CEnumerationPtr ptrTriggerSel = cameraNodeMap.GetNode ("TriggerSelector"); ptrTriggerSel->FromString("FrameStart"); CEnumerationPtr ptrTrigger = cameraNodeMap.GetNode ("TriggerMode"); #ifdef Real_Freerun ptrTrigger->SetIntValue(0); #else //Software ptrTrigger->SetIntValue(1); CEnumerationPtr ptrTriggerSource = cameraNodeMap.GetNode ("TriggerSource"); ptrTriggerSource->FromString("Software"); #endif } break; case Type_Basler_Line1: { CEnumerationPtr ptrTriggerSel = cameraNodeMap.GetNode ("TriggerSelector"); ptrTriggerSel->FromString("FrameStart"); CEnumerationPtr ptrTrigger = cameraNodeMap.GetNode ("TriggerMode"); ptrTrigger->SetIntValue(1); CEnumerationPtr ptrTriggerSource = cameraNodeMap.GetNode ("TriggerSource"); ptrTriggerSource->FromString("Line1"); } break; case Type_Basler_ExposureTimeAbs: { const CFloatPtr exposureTime = cameraNodeMap.GetNode("ExposureTimeAbs"); exposureTime->SetValue(tmpValue); } break; case Type_Basler_GainRaw: { const CIntegerPtr cameraGen = cameraNodeMap.GetNode("GainRaw"); cameraGen->SetValue(tmpValue); } break; case Type_Basler_AcquisitionFrameRateAbs: { const CBooleanPtr frameRate = cameraNodeMap.GetNode("AcquisitionFrameRateEnable"); frameRate->SetValue(TRUE); const CFloatPtr frameRateABS = cameraNodeMap.GetNode("AcquisitionFrameRateAbs"); frameRateABS->SetValue(tmpValue); } break; case Type_Basler_Width: { const CIntegerPtr widthPic = cameraNodeMap.GetNode("Width"); widthPic->SetValue(tmpValue); } break; case Type_Basler_Height: { const CIntegerPtr heightPic = cameraNodeMap.GetNode("Height"); heightPic->SetValue(tmpValue); } break; case Type_Basler_LineSource: { CEnumerationPtr ptrLineSource = cameraNodeMap.GetNode ("LineSource"); ptrLineSource->SetIntValue(2); } break; default: break; } } double SBaslerCameraControl::GetCamera(SBaslerCameraControl::SBaslerCameraControl_Type index) { INodeMap &cameraNodeMap = m_basler.GetNodeMap(); switch (index) { case Type_Basler_ExposureTimeAbs: { const CFloatPtr exposureTime = cameraNodeMap.GetNode("ExposureTimeAbs"); return exposureTime->GetValue(); } break; case Type_Basler_GainRaw: { const CIntegerPtr cameraGen = cameraNodeMap.GetNode("GainRaw"); return cameraGen->GetValue(); } break; case Type_Basler_AcquisitionFrameRateAbs: { const CBooleanPtr frameRate = cameraNodeMap.GetNode("AcquisitionFrameRateEnable"); frameRate->SetValue(TRUE); const CFloatPtr frameRateABS = cameraNodeMap.GetNode("AcquisitionFrameRateAbs"); return frameRateABS->GetValue(); } break; case Type_Basler_Width: { const CIntegerPtr widthPic = cameraNodeMap.GetNode("Width"); return widthPic->GetValue(); } break; case Type_Basler_Height: { const CIntegerPtr heightPic = cameraNodeMap.GetNode("Height"); return heightPic->GetValue(); } break; default: return -1; break; } } long SBaslerCameraControl::StartAcquire() { m_isOpenAcquire = true; qDebug() << "SBaslerCameraControl IsGrabbing"; try { qDebug() << "SBaslerCameraControl StartAcquire" << m_currentMode; if(m_currentMode == "Freerun") { m_basler.StartGrabbing(GrabStrategy_LatestImageOnly,GrabLoop_ProvidedByInstantCamera); } else if(m_currentMode == "Software") { m_basler.StartGrabbing(GrabStrategy_LatestImageOnly); onTimerGrabImage(); } else if(m_currentMode == "Line1") { m_basler.StartGrabbing(GrabStrategy_OneByOne); } else if(m_currentMode == "Line2") { m_basler.StartGrabbing(GrabStrategy_OneByOne); } } catch (GenICam::GenericException &e) { OutputDebugString(L"StartAcquire error:"); return -2; } return 0; } long SBaslerCameraControl::StopAcquire() { m_isOpenAcquire = false; qDebug() << "SBaslerCameraControl StopAcquire"; try { if (m_basler.IsGrabbing()) { m_basler.StopGrabbing(); } } catch (GenICam::GenericException &e) { OutputDebugString(LPCWSTR(e.GetDescription())); return -2; } return 0; } long SBaslerCameraControl::GrabImage(QImage &image, int timeout) { try { if (!m_basler.IsGrabbing()) { StartAcquire(); } CGrabResultPtr ptrGrabResult; if(m_currentMode == "Freerun") { } else if(m_currentMode == "Software") { if (m_basler.WaitForFrameTriggerReady(1000, TimeoutHandling_Return)) { m_basler.ExecuteSoftwareTrigger(); m_basler.RetrieveResult(timeout, ptrGrabResult,TimeoutHandling_Return); } } else if(m_currentMode == "Line1") { m_basler.RetrieveResult(timeout, ptrGrabResult, TimeoutHandling_Return); } else if(m_currentMode == "Line2") { m_basler.RetrieveResult(timeout, ptrGrabResult, TimeoutHandling_Return); } if (ptrGrabResult->GrabSucceeded()) { if (!ptrGrabResult.IsValid()) { OutputDebugString(L"GrabResult not Valid Error\n"); return -1; } EPixelType pixelType = ptrGrabResult->GetPixelType(); switch (pixelType) { case PixelType_Mono8: { CopyToImage(ptrGrabResult, image); } break; case PixelType_BayerRG8: { qDebug() << "what: PixelType_BayerRG8"; } break; default: qDebug() << "what: default"; break; } } else { OutputDebugString(L"Grab Error!!!"); return -3; } } catch (GenICam::GenericException &e) { OutputDebugString(L"GrabImage Error\n"); return -2; } catch(...) { OutputDebugString(L"ZP 11 Shot GetParam Try 12 No know Error\n"); return -1; } return 0; }
如何調(diào)用
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include "BaslerCamera/sbaslercameracontrol.h" namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void on_pushButton_GetExTime_clicked(); void on_pushButton_SetExTime_clicked(); void on_pushButton_SetMode_clicked(); void on_pushButton_GetMode_clicked(); void on_pushButton_CFMode_clicked(); void on_comboBox_CFMode_activated(int index); void on_pushButton_Start_clicked(); void on_pushButtonRotate_clicked(); private: Ui::MainWindow *ui; SBaslerCameraControl* m_control = Q_NULLPTR; QMatrix m_matrix; }; #endif // MAINWINDOW_H
源文件:
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); m_control = new SBaslerCameraControl(this); m_control->initSome(); connect(m_control, &SBaslerCameraControl::sigCurrentImage, [=](QImage img){ QPixmap pix = QPixmap::fromImage(img).transformed(m_matrix); ui->label->setPixmap(pix); ui->widget_pic->setFixedSize(pix.size()); }); connect(m_control, &SBaslerCameraControl::sigSizeChange, [=](QSize size){ // 默認(rèn)大小641,494 ui->label_size->setText(QString("\345\260\272\345\257\270:%0*%1").arg(QString::number(size.width())).arg(QString::number(size.height()))); // 尺寸 ui->widget_pic->setFixedSize(size); }); m_control->OpenCamera(m_control->cameras().first()); } MainWindow::~MainWindow() { m_control->CloseCamera(); m_control->deleteAll(); delete ui; } void MainWindow::on_pushButton_GetExTime_clicked() { ui->label_exTime->setText(QString::number(m_control->getExposureTime())); } void MainWindow::on_pushButton_SetExTime_clicked() { m_control->setExposureTime(ui->lineEdit_exTime->text().toDouble()); } void MainWindow::on_pushButton_SetMode_clicked() { m_control->setFeatureTriggerSourceType(ui->lineEdit_SetMode->text()); } void MainWindow::on_pushButton_GetMode_clicked() { ui->label_Mode->setText(m_control->getFeatureTriggerSourceType()); } void MainWindow::on_pushButton_CFMode_clicked() { ui->label_CFMode->setText(m_control->getFeatureTriggerModeType()?"Open":"Close"); } void MainWindow::on_comboBox_CFMode_activated(int index) { m_control->setFeatureTriggerModeType(index == 0); } void MainWindow::on_pushButton_Start_clicked() { if(ui->pushButton_Start->text() == "\345\274\200\345\247\213\351\207\207\351\233\206") {// 開(kāi)始采集 m_control->StartAcquire(); ui->pushButton_Start->setText("\347\273\223\346\235\237\351\207\207\351\233\206");// 結(jié)束采集 } else { m_control->StopAcquire(); ui->pushButton_Start->setText("\345\274\200\345\247\213\351\207\207\351\233\206");// 開(kāi)始采集 } } void MainWindow::on_pushButtonRotate_clicked() { m_matrix.rotate(90); }
pro文件
(注意:引用庫(kù)文件的路徑哦)
#------------------------------------------------- # # Project created by QtCreator 2017-12-14T17:55:52 # #------------------------------------------------- QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = Demo_BaslerCamera TEMPLATE = app CONFIG += c++11 #--------------------------------------------Basler------------------------------------------- INCLUDEPATH += $$PWD/include LIBS += -L$$PWD/lib/Win32 -lGCBase_MD_VC120_v3_0_Basler_pylon_v5_0 -lGenApi_MD_VC120_v3_0_Basler_pylon_v5_0 -lPylonBase_MD_VC120_v5_0 -lPylonC_MD_VC120 -lPylonGUI_MD_VC120_v5_0 -lPylonUtility_MD_VC120_v5_0 #---------------------------------------------------------------------------------------------- SOURCES += main.cpp\ mainwindow.cpp \ BaslerCamera/sbaslercameracontrol.cpp HEADERS += mainwindow.h \ BaslerCamera/sbaslercameracontrol.h FORMS += mainwindow.ui
我把源碼已經(jīng)上傳到碼云和Github
碼云
https://gitee.com/ShaShiDiZhuanLan/Demo_BaslerCamera
Github
https://github.com/ShaShiDiZhuanLan/Demo_BaslerCamera_Qt
到此這篇關(guān)于Qt(C++)調(diào)用工業(yè)相機(jī)Basler的SDK使用示例的文章就介紹到這了,更多相關(guān)Qt調(diào)用Basler的SDK內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于c++11與c風(fēng)格路徑拼接的速度對(duì)比
這篇文章主要介紹了關(guān)于c++11與c風(fēng)格路徑拼接的速度對(duì)比分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07深入分析Visual C++進(jìn)行串口通信編程的詳解
本篇文章是對(duì)Visual C++進(jìn)行串口通信編程進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05Matlab實(shí)現(xiàn)獲取文件夾下所有指定后綴的文件
這篇文章主要為大家詳細(xì)介紹了Matlab如何獲取文件夾下所有指定后綴的文件(包含子文件夾),文中的示例代碼講解詳細(xì),感興趣的可以嘗試一下2022-11-11c++中new一個(gè)結(jié)構(gòu)體初始化過(guò)程
這篇文章主要介紹了c++中new一個(gè)結(jié)構(gòu)體初始化過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08c++基礎(chǔ)語(yǔ)法:構(gòu)造函數(shù)與析構(gòu)函數(shù)
構(gòu)造函數(shù)用來(lái)構(gòu)造一個(gè)對(duì)象,主要完成一些初始化工作,如果類(lèi)中不提供構(gòu)造函數(shù),編譯器會(huì)默認(rèn)的提供一個(gè)默認(rèn)構(gòu)造函數(shù)(參數(shù)為空的構(gòu)造函數(shù)就是默認(rèn)構(gòu)造函數(shù)) ;析構(gòu)函數(shù)是隱式調(diào)用的,delete對(duì)象時(shí)候會(huì)自動(dòng)調(diào)用完成對(duì)象的清理工作2013-09-09用C語(yǔ)言求解第N項(xiàng)斐波那契數(shù)列問(wèn)題
這篇文章主要介紹了用C語(yǔ)言求解第N項(xiàng)斐波那契數(shù)列問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11C/C++中不同數(shù)據(jù)類(lèi)型之間的轉(zhuǎn)換詳解
這篇文章主要介紹了C/C++中不同數(shù)據(jù)類(lèi)型之間的轉(zhuǎn)換詳解,數(shù)據(jù)類(lèi)型轉(zhuǎn)換是計(jì)算機(jī)編程中常見(jiàn)的操作,用于將一個(gè)數(shù)據(jù)類(lèi)型轉(zhuǎn)換為另一個(gè)數(shù)據(jù)類(lèi)型,本文將對(duì)不同數(shù)據(jù)類(lèi)型之間的轉(zhuǎn)換作出說(shuō)明,需要的朋友可以參考下2023-10-10