跳到主要內容

C++ CURL 下載圖片

想要把之前的專題架設在RPI
原本要從廠商提供的SDK向DVR主機
拉H264串流下來解碼成圖片做處理
可是!

他沒有提供ARM的動態函式庫...
(虧我還花了一天找RPI硬解H264)

所以尋找替代方案!
所幸DVR提供網頁線上瀏覽
直接抓圖下來
連轉檔都省下來了!!

再拉圖下來有Authorization問題
要輸入帳號密碼才能登入下載

有兩種解法
以我這邊的DVR網址為例
原網址為
http://127.0.0.1/cgi-bin/net_jpeg.cgi?ch=0

第一種
再前面加入"帳號:密碼@"如下
http://user:pass@127.0.0.1/cgi-bin/net_jpeg.cgi?ch=0

第二種
再Header 自己添加Authorization
headers = curl_slist_append(headers,"Authorization: Basic XXXXXXXXXXX");
XXXXXXXXXXX為 user:pass 進行 base64運算結果
詳情參考WIKI:HTTP基本認證

後記:
再抓DVR的圖時間耗費的很久
原本以為是keep-alive的問題減少握手次數因該可以加快速度
我還以為是我程式碼寫錯
結果DVR主機不支援........
而花費的時間大都再內部的轉檔吧!(猜測)

使用範例multi-app
去同時抓圖下來(16張)
大概花費2秒
比原本一張1秒好多了
不過同時抓有時候程式會卡住...
不知道是主機來不及反應還是網路塞車了

下面程式碼使用QT且只能單張下載
可以參考multi-app修改

dlimage.h
#ifndef DIMAGE_H
#define DIMAGE_H

#include <curl/curl.h>
#include <QString>
#include <QImage>

class DLimage
{
public:
    DLimage(QString srcUrl);

public:
    bool ChangeUrl(QString srcUrl);
    bool DownloadJpeg();
    QImage& GetImage();

private:
    QString srcUrl;
    QByteArray tempfile ;
    QImage newImage;
};

#endif // DIMAGE_H

dlimage.cpp
#include "dlimage.h"
#include<iostream>
#include<QImageReader>
#include <QBuffer>

DLimage::DLimage(QString srcUrl)
{
    this->srcUrl=srcUrl;
}
bool DLimage::ChangeUrl(QString srcUrl)
{
    this->srcUrl=srcUrl;
    return true;
}
size_t callbackfunction(void *ptr, size_t size, size_t nmemb, void* userdata)
{
    int len= size*nmemb;
    QByteArray *tempfile =(QByteArray*) userdata;
    tempfile->append(QByteArray((char*)ptr,nmemb));

    return len;
}
bool DLimage::DownloadJpeg()
{
    CURL* curlCtx = curl_easy_init();
    struct curl_slist *headers = NULL;

    headers = curl_slist_append(headers,"Connection:keep-alive");
    headers = curl_slist_append(headers,"Authorization: Basic XXXXXXXXXXX"); //base64 

    curl_easy_setopt(curlCtx, CURLOPT_HTTPHEADER, headers);
    curl_easy_setopt(curlCtx, CURLOPT_URL,srcUrl.toLocal8Bit().constData());
    curl_easy_setopt(curlCtx, CURLOPT_WRITEDATA,&tempfile);
    curl_easy_setopt(curlCtx, CURLOPT_WRITEFUNCTION, callbackfunction);
    curl_easy_setopt(curlCtx, CURLOPT_FOLLOWLOCATION, 1);

    CURLcode rc = curl_easy_perform(curlCtx);
    if (rc)
    {
        std::cout<<"!!! Failed to download: "<<srcUrl.toLocal8Bit().constData()<<std::endl;
        return false;
    }

    long res_code = 0;
    curl_easy_getinfo(curlCtx, CURLINFO_RESPONSE_CODE, &res_code);
    if (!((res_code == 200 || res_code == 201) && rc != CURLE_ABORTED_BY_CALLBACK))
    {
        std::cout<<"!!! Response code: "<<res_code<<std::endl;
        return false;
    }

    curl_easy_cleanup(curlCtx);
    curl_slist_free_all(headers);
    headers = NULL;

    //save Image from QByteArray
    QBuffer buffer(&tempfile);
    buffer.open( QIODevice::ReadOnly);
    QImageReader reader(&buffer);
    newImage = reader.read();//Copy
    buffer.close();
    tempfile.clear();

    return true;
}
QImage& DLimage::GetImage()
{
    return newImage;
}

留言

這個網誌中的熱門文章

小蟻智慧攝影機支援RTSP

來源: http://en.miui.com/thread-196713-1-1.html 小蟻智慧攝影機版本: 1.8.5.1l_201511061661(台灣版) 下載檔案 https://drive.google.com/file/d/0ByjBix7wpeJJY0ZWZXlvWl9Za1E/view?usp=sharing 把攝影機SD卡拿讀卡機讀取 把壓縮檔內的test資料夾放進SD根目錄 插回SD卡至攝影機 重開 攝影機會呈現橘燈並執行更新 等恢復至藍燈或是用app確認攝影機開啟 用VLC或相關程式讀取串流 Main stream:rtsp:// <CameraIP> :554/ch0_0.h264 Minor stream:rtsp:// <CameraIP> :554/ch0_1.h264 Audio stream:rtsp:// <CameraIP> :554/ch0_3.h264 Telnet與FTP開啟加上 # Telnet if [ ! -f "/etc/init.d/S88telnet" ]; then     echo "#!/bin/sh" > /etc/init.d/S88telnet     echo "telnetd &" >> /etc/init.d/S88telnet     chmod 755 /etc/init.d/S88telnet fi # FTP echo "#!/bin/sh" > /etc/init.d/S89ftp echo "tcpsvd -vE 0.0.0.0 21 ftpd -w / &" >> /etc/init.d/S89ftp chmod 755 /etc/init.d/S89ftp User:  root Password:  1234qwer 使用passwd改密碼 參考: http://en.miui.com/thread-224653-1-1.html

Arduino 滑鼠滾輪編碼器/旋轉編碼器

滑鼠拆下來的滾輪編碼器 時序為                      → CW A  -----------          -------------    HIGH                ----------                  LOW                      ← CCW B  --------          ----------------    HIGH             ----------                     LOW A B 1  1↓CW 1  0 0  0 0  1 1  1 1  0 0  0 0  1↑CCW 程式碼參考底下網址來源修改而來 #define ENCODER_A_PIN 2 #define ENCODER_B_PIN 3 unsigned long time = 0; long position = 0; long num = 0; void setup() { pinMode(ENCODER_A_PIN,INPUT); pinMode(ENCODER_B_PIN,INPUT); attachInterrupt(0, RotaryEncoder, LOW); Serial.begin(9600); time = millis(); } void loop() { while (num != position) { num = position; Serial.println(num); } } void RotaryEncoder(){ int temp =digitalRead(ENCODER_B_PIN); if ((millis() - time) > 3) { if ( temp == LOW) { position++; }else{ if ( temp == HIGH) position--; } } time = millis(); } 沒中斷版本 int trigger=0; void Rotar

Voip SPA3000/9000 設定

架設Voip 1.Analog Telephone Adaptor (ATA) 一個類比電話轉換到基於數位VoIP電話網路 An ATA contains the following components: FXS Ports – Used for interfacing with analog telephones. RJ45 Ports – Used for interfacing with the LAN/WAN FXO Ports – Used for interfacing with the PSTN 2.網絡電話交換機(IPPBX) 能通過IP網提供語音、視頻以及即時消息通信。這些通信不僅可以在企業內部網上進行,也可以通過Internet與外網甚至PSTN(Public Switched Telephone Network)電話間進行。 3.網路電話(IPPHONE) SPA921、支援SIP應用程式或電話 SPA3000設定 參照: 安德森技術備忘板 參照 OSSLab 的設定設完發現會PSTN接到來電時 等到 PSTN Answer Delay 秒數過後將會自動接起外線 仍然等待Voip分機接起話筒可能會造成撥打者不必要的電話費 可能原因是 Off Hook While Calling VoIP  被設為Yes SPA9000設定 Wan Setup Internet Connection Settings Connection Type: DHCP Static IP PPPOE PPPOE,DHCP DHCP,PPPOE SIP Hunt Groups: 設定群組獵線 群組號碼為500,分機100-102, 響鈴300秒 回到SPA3000 PSTN Line Dial Plan 2: 來電時將轉接至群組 發現的問題: 剛開機使用SPA3000 LINE1 撥打至PSTN Line 分機 在打外線會導致所有分機都將無法在外線 開完機後先用其他分機撥打測試後就可正常使用