2017年10月25日 星期三

Visual Studio 如何完全隱藏執行視窗 console

Visual Studio 如何完全隱藏執行視窗 console

找了不少方法有蠻多都是這個,不過這個只是變得快一點消失而已,還是會閃一下
HWND hWnd = GetConsoleWindow();
ShowWindow(hWnd, SW_HIDE);
後來找到比較實用完全隱藏的方法
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")

2017年10月24日 星期二

C++ 複製剪貼簿內容並寫入檔案 [寬字元處理方法]

C++ 複製剪貼簿內容並寫入檔案 [寬字元處理方法]

這一篇是擷取剪貼簿內容,需要將文字複製到剪貼簿上(Ctrl+C)的請參考這一篇:
http://charlottehong.blogspot.com/2017/10/c_25.html
卡關卡很久的地方
  1. UTF-8原來是要檔頭的,一開始沒注意到嘗試超久,sublimetext開出來都一堆碼
  2. CStringW 如何轉型 char* 這個也弄很久
下面直接上幾個重要的函式
#include <windows.h>
#include <atlstr.h> 

//獲取剪貼簿
CStringW getClipboard(){
    /* 轉型(char*)(LPCSTR)(CStringA)
    剪貼簿參考:https://goo.gl/bjzEeA
    轉型參考:https://goo.gl/bEmvbU */
    CStringW strData;
    if (OpenClipboard(NULL)) {
        HANDLE hClipboardData = GetClipboardData(CF_UNICODETEXT);
        //DWORD dwLength = GlobalSize(hClipboardData);
        if (hClipboardData) {
            WCHAR *pchData = (WCHAR*)GlobalLock(hClipboardData);
            if (pchData) {
                strData = pchData;
                GlobalUnlock(hClipboardData);
            }
        }
        CloseClipboard();
    }
    return strData; 
}

// 寫入文件
void WriteFiles(char* fileName, const CStringW& ClipStrW) {
    ofstream file (fileName, ios::binary);
    file.exceptions (ifstream::eofbit | ifstream::failbit | ifstream::badbit);
    // CP_UTF8 檔頭
    int UTF_8 = 0xBFBBEF;
    file.write((char*)&UTF_8, 3);
    // 寫入 CP_UTF8
    wstring str = ClipStrW;
    string result = std::string();
    result.resize(WideCharToMultiByte(CP_UTF8, 0, str.c_str(), -1, NULL, 0, 0, 0) - 1);
    char* ptr = &result[0];
    WideCharToMultiByte(CP_UTF8, 0, str.c_str(), -1, ptr, result.size(), 0, 0);
    file << result;
}
main的操作方式如下
#include <windows.h>
#include <atlstr.h> 

    // 獲取剪貼簿內容 “salient”
    CStringW ClipStrW = getClipboard();
    const char* ClipStr = (LPCSTR)(CStringA)ClipStrW;
    //cout << ClipStr << endl;
    // 剪貼簿內容寫入文件
    WriteFiles("Paper.txt", ClipStrW);

2017年10月11日 星期三

台灣 支付寶 實名驗證圖文步驟[不須大陸門號或銀行卡]

台灣 支付寶 實名驗證圖文步驟[不須大陸門號或銀行卡]

微信支付不確定能不能用,3月份以來突然就一堆狀況,不過我自己在此之前驗證過的老帳戶倒是沒影響還可以正常使用。
如果需要在台灣使用大陸的支付系統,或是要過去旅遊的,可以直接辦台胞證然後申請支付寶就好;權限也比微信還要多一些,可以給商家掃馬,微信只綁台灣信用卡只能掃別人不能給商家掃。

台胞證所需項目

  • 最高標準大頭照 1~2 組
  • 護照 $900
  • 台胞證 $1700 (急件$2500)
後面兩項到各大旅行社就可以辦了,應該可以一條龍去了跟他說我要這兩樣一次辦好。

照片注意事項

  • 3個月內照片
  • 深色衣服
  • 露出五官
注意!台胞證要把護照跟證件一起送過去大陸審核,大陸那邊檢查很嚴格是真的會因為照片退件的,建議去像館直接跟老闆說我要辦台胞證,老闆就會幫你注意了,退件的話一來一往就是一周的時間了,建議還是一次弄好比較省事。
3個月雖然看不出來,至少不要拿跟護照同一組,護照上面有申辦日期如果護照很久之前辦的會被看出來。

淘寶實名驗證

有申請過掏寶帳號的話直接使用掏寶帳號就可以登入了,如果沒有的話申請一下也是很快的,可能會需要簡訊驗證。
再來先到右下角的 我的 裡面開啟驗證信息, 點擊實名驗證。
這裡橘色的字請完善實名驗證,點進去就可以開始驗證了,如果沒有請點擊你的帳號名稱或頭像,進入之後選擇身分驗證。
如果是白帳號這時候會要你設定支付密碼,輸入兩次設定完成,記住千萬不能忘記!
再來會要你填入身分證信息,選擇台灣居民往來大陸通行證,也就是台胞證的全寫。

身分證資訊填寫有誤

這個不是每個人都會遇到,我自己是遇到了XD
有些人拿到的卡,明明依照信息填入卻還是出現 身分證資訊填寫有誤 ,處理方式就是年分 -1 ,比如說我拿到的 2022 到期,先填入一次正確的出現錯誤之後再填入 2021 ,就可以過了。
看回復有些人有效,也有些人沒效的,自己在多確定有沒有其他地方打錯,然後年分各種數字試試看 -1 -2 -3 等等

輸入簡體姓名

這裡要注意的是姓名要填簡體的,有幾個方法輸入
有些人簡體跟繁體一樣可以直接打就好會過
轉換可以參考google翻譯,我已經幫你點好選項了
https://translate.google.com.tw/?hl=zh-TW&tab=wT#zh-CN/zh-CN/%E7%B0%A1%E9%AB%94
直接在手機上點進去網址之後,輸入你的名字就會轉成簡體了,然後在用複製的方式貼回支付寶上,這樣就不會出錯了。

人臉驗證

上面都輸入完畢之後下一關選人臉驗證,進去之後依照指示對著鏡頭眨眼就成功了,好像沒什麼特別需要注意的地方。
2017.10 在大陸實測可以正常支付百貨公司,給店家掃QR碼支付。
回台灣之後有到ok商店測試,會彈出需要大陸身分證驗證才可以使用。


儲值

付款部分是沒辦法用境外卡的刷卡的~會刷不過,只能靠第三方儲值使用
可以參考這邊站內文章,使用幫幫寶儲值,儲值後餘額就可以使用了。
這邊是儲值微信的支付寶改一下選項(本來點微信改成點支付寶),後續操作是一樣的。
如果要去大陸玩,也是可以帶現金給導遊或其他大陸人然後直接轉給你


確認開通成功

提供站方的贊助連結,需要確認可以掃描支付測試~

2017年10月6日 星期五

Windows10 開機自動啟動程式 資料夾位置

Windows10 開機自動啟動程式 資料夾位置

傳統的XP只要到開始裡面尋找,啟動這個資料夾把捷徑放進去就可以自動啟動了,到了Win10之後這個資料夾就不見了。
其實他還在而且還有兩個位置,一個是公用的一個是使用者的,下面是使用者的位置,放在使用者裡面,只會影響該使用者,放在公用裡面則是這台電腦任何人登入都有。
這裡是啟動的路徑:
%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup
也可以使用
shell:startup

隨便開一個資料夾,把路徑複製貼上之後把你要的捷徑複製進去就好了;捷徑怎麼獲得可以直接從開始裡面搜尋,找到之後按右鍵開啟檔案位置。

公用的位置
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup



Windows10 多使用者,刪除桌面圖示其他使用者跟著被刪除

Windows10 多使用者,刪除桌面圖示其他使用者跟著被刪除

這個問題主要是因為有些軟體放置的捷徑路徑不是放在使用者內,而是放在公用資料夾內,有在注意的人看安裝訊息的人應該看過會讓你決定是要替所有使用者安裝,還是只替當前使用者安裝,這句話的意思就是要安裝到公用資料夾還是個人資料夾。
所有使用者的桌面或開始程式集裡面都會包含公用使用者
這就是問題所在拉~導致你在A使用者砍掉圖示之後B使用者開上圖示捷徑也跟著不見,解決就是去公用資料夾,把圖示移動到自己的桌面就好。
下面分別給當前使用者與公用使用者的路徑,路徑是相對直徑直接貼上即可自動對應到你的使用者名稱。
公用桌面:%SystemDrive%\Users\Public\Desktop
當前使用者桌面:%USERPROFILE%\Desktop

2017年10月4日 星期三

C / C++ 影像處理如何畫線與畫箭頭

C++ 影像處理如何畫線與畫箭頭

代碼關鍵函式要用點斜式,然後用for迴圈去跑x軸或y軸,跑完那一條線
struct ImgRaw{
    int width;
    int height;
    vector<unsigned char> raw_img;
};

void drawLine_p(ImgRaw& img, int y, int x, int y2, int x2, float val) {
    // 兩點之間的距離差
    float dx = static_cast<float>(x2-x);
    float dy = static_cast<float>(y2-y);
    // 以Y軸為主
    float sita=fastAtan2f(dy, dx);
    if (sita>45 and sita<135 or sita>225 and sita<315) {
        float slopeY = dx/dy; // 斜率
        for (int i = 0; i < abs(dy); i++) {
            int iFix = dy>0? i:-i;
            int currPos = static_cast<int>(iFix*slopeY+.5f + x);

            int distX = currPos;
            int distY = y+iFix;

            if (distX<0 or distX>=(int)img.width or distY<0 or distY>=(int)img.height) {
                return;
            }
            img.raw_img[distY*img.width + distX] = static_cast<unsigned char>(val);
        }
    } 
    // 以X軸為主
    else {
        float slopeX = dy/dx; // 斜率
        for (int i = 0; i < abs(dx); i++) {
            int iFix = dx>0? i:-i;
            int currPos = static_cast<int>(iFix*slopeX+.5 + y);

            int distX = x+iFix;
            int distY = currPos;

            if (distX<0 or distX>=(int)img.width or distY<0 or distY>=(int)img.height) {
                return;
            }
            img.raw_img[distY*img.width + distX] = (unsigned char)val;
        }
    }
}
然後角度的不一樣比如說45~90度跑Y軸會比較好,線連得比較密,如果是0~45度則是跑X軸比較好,才不會出現斷線。
角度的判斷計算使用。
float sita = fastAtan2f(dy, dx);
  • ImgRaw帶有圖像資訊、長、寬
  • fastAtan2f是從OpenCV複製出來的可以參考站內文這裡
接下來有了直線之後就是寫一個,輸入角度與長度的函式,簡單來說就是算出頭尾的位置然後帶入剛剛的函式畫線。
void drawLineRGB_s(ImgRaw& img, int y, int x, float line_len, float sg) {
        // 檢查
        if (line_len <= 0) { return; }
        // 算頭尾
        int x2 = x + line_len*cos(sg * M_PI/180);
        int y2 = y + line_len*sin(sg * M_PI/180);
        // 畫線
        drawLineRGB_p(img, y, x, y2, x2);
    }
再來箭頭就只是多話2條線,帶入剛剛的給點給角度的函式畫出箭頭
void draw_arrowRGB(ImgRaw& img, int y, int x, float line_len, float sg) {
        // 檢查
        if (line_len <= 0) { return; }
        // 算頭尾
        int x2 = x + line_len*cos(sg * M_PI/180);
        int y2 = y + line_len*sin(sg * M_PI/180);
        // 畫線
        drawLineRGB_p(img, y, x, y2, x2);
        // 畫頭
        drawLineRGB_s(img, y2, x2, 10, sg-150);
        drawLineRGB_s(img, y2, x2, 10, sg+150);
    }


如何使用

drawLine有兩個,一個是給定兩個點,把他們連起來,另一個是給定原點, 長度, 角度,也就是給極值的方式畫線。
    ImgRaw img_lineRGB(1280, 720);
    for (size_t i = 0; i < 36; i++) {
        Draw::draw_arrowRGB(img_lineRGB, 200, 200, 100.f*sqrt(2), i*10);
    } img_lineRGB.bmp("lineRGB.bmp");
ImgRaw 做的事情很簡單只是開一個 vector(1280*720*3) 然後儲存他的長1280和寬720
畫一圈的箭頭

原理

主要是利用斜率去算的,假設有兩個點,分別是 (0, 0) 與 (40,50) 斜率的公式,其中b是偏移量暫時不管她。
y=ax+b;
斜率就只是相減而已
dy=50-0;
dx=40-0;

m=dy/dx;
既然已知斜率那就用for迴圈去跑x的範圍 0~40 就可以得出y的位置了
不過這會遇到一個問題是當直線是上下的時候 for 迴圈跑的次數是0畫不出線,其次可以發現這種畫法當線條比較偏上的時候,45~135度的範圍會明顯斷線的感覺,因此這時候要變成以y為主,for迴圈去跑y反向計算出x。
這樣就可以畫出上圖比較好看一些的線條了。


範例程式

完整的程式參考:https://goo.gl/rAJLjH

atan() 和 atan2() 快速算法

atan() 計算的時候如何得知正確角度;fastAtan2f() 快速計算方法

atan() 在計算的時候是沒有把dx和dy的正負號考慮進去的,也就是說在第3象限的時候會被當作第一象限來處理。
解決方法很容易,有一個已經幫你處好的函式是 atan2() 可以直接輸入 atan2(dy, dx) 計算出正確的結果,不過出來的角度是 -PI~PI 逕度還需要處理一下轉為角度。
這裡提供一個已經處理好上述而且速度更快的方法,是來自於OpenCV內的函式原封不動複製出來的應該足夠安全。

atan2()

static inline float fastAtan2f(float dy, float dx){
    // 快速atan運算
    static const float atan2_p1 = 0.9997878412794807f*(float)(180/M_PI);
    static const float atan2_p3 = -0.3258083974640975f*(float)(180/M_PI);
    static const float atan2_p5 = 0.1555786518463281f*(float)(180/M_PI);
    static const float atan2_p7 = -0.04432655554792128f*(float)(180/M_PI);
    static const float atan2_DBL_EPSILON = 2.2204460492503131e-016;

    float ax = std::abs(dx), ay = std::abs(dy);
    float a, c, c2;
    if (ax >= ay) {
        c = ay/(ax + static_cast<float>(atan2_DBL_EPSILON));
        c2 = c*c;
        a = (((atan2_p7*c2 + atan2_p5)*c2 + atan2_p3)*c2 + atan2_p1)*c;
    } else {
        c = ax/(ay + static_cast<float>(atan2_DBL_EPSILON));
        c2 = c*c;
        a = 90.f - (((atan2_p7*c2 + atan2_p5)*c2 + atan2_p3)*c2 + atan2_p1)*c;
    }
    if (dx < 0)
        a = 180.f - a;
    if (dy < 0)
        a = 360.f - a;
    return a;
}
fastAtan2f() 計算出來就是 0~360 度的角度了,如果需要逕度從代碼內把轉換的移除即可。
M_PI 可能需要自己定義一下,或者引入cmath並啟用宏定義(啟用是一行宏定義的代碼需要再自己查)。
如果只是單單需要拍自己定一個比較快~
#define M_PI 3.14159265358979323846

atan()

這個OpenCV裡面就沒有,不過可以從上面的 atan2() 修改一下即可(簡單來說就是x設定成1)。
這個比較常用到逕度版本的我貼逕度版本的
float fastAtanf_rad(float dy){
    static const float atan2_p1 =  0.9997878412794807f;
    static const float atan2_p3 = -0.3258083974640975f;
    static const float atan2_p5 =  0.1555786518463281f;
    static const float atan2_p7 = -0.04432655554792128f;
    static const float atan2_DBL_EPSILON = 2.2204460492503131e-016;

    float ax = 1.0, ay = std::abs(dy);
    float a, c, c2;
    if (ax >= ay) {
        c = ay/(ax + static_cast<float>(atan2_DBL_EPSILON));
        c2 = c*c;
        a = (((atan2_p7*c2 + atan2_p5)*c2 + atan2_p3)*c2 + atan2_p1)*c;
    } else {
        c = ax/(ay + static_cast<float>(atan2_DBL_EPSILON));
        c2 = c*c;
        a = M_PI*0.5 - (((atan2_p7*c2 + atan2_p5)*c2 + atan2_p3)*c2 + atan2_p1)*c;
    }

    if (dy < 0)
        a = - a;

    return a;
}
這一分我有做簡單的驗證是沒問題的,可以參照底下的代碼有過程,敏感場合建議自己在想方法驗證一次~

其他

全部一共4個版本,atan()和atan2() 以及他們的 逕度版本與角度版本。