Java調(diào)用耗裕康sdk操作熱成像設(shè)備獲取對(duì)應(yīng)點(diǎn)溫度

Java調(diào)用海康sdk操作熱成像設(shè)備獲取對(duì)應(yīng)點(diǎn)溫度轴捎, 汉缀校康官方提供有Java版的sdk蚕脏,遺憾的是里面提供的api比較舊了新版的api需要根據(jù)c++版的開(kāi)發(fā)文檔自己寫(xiě)對(duì)應(yīng)的java接口和類。這對(duì)于不熟悉c++的開(kāi)發(fā)人員比較吃力侦锯。下面的代碼示例了通過(guò)和毡蓿康的SDK獲取熱成像畫(huà)面上某一點(diǎn)的具體溫度。目前已經(jīng)使用Python實(shí)現(xiàn)了相應(yīng)的效果尺碰,有需要Python版本的可以留言挣棕。
maven依賴

        <dependency>
            <groupId>com.sun.jna</groupId>
            <artifactId>jna</artifactId>
            <version>3.0.9</version>
        </dependency>
import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import lombok.extern.slf4j.Slf4j;

import java.nio.ByteBuffer;

/**
 * 調(diào)用demo
 *
 * @author JW
 * @version 1.0
 * @date 2021/3/25 14:47
 */
@Slf4j
public class HKNetApp {

    private NativeLong lUserID = new NativeLong(-1);//用戶句柄
    private HCNetSDK.NET_DVR_DEVICEINFO_V30 m_strDeviceInfo;//設(shè)備信息

    static HCNetSDK hCNetSDK = null;//sdk

    public static synchronized void loadLibrary(String libraryPath){
        if(null == hCNetSDK){
            hCNetSDK = (HCNetSDK) Native.loadLibrary(libraryPath, HCNetSDK.class);
        }
    }

    public static void main(String[] args) {
        loadLibrary("你的sdk地址");

        HKNetApp hkNetApp = new HKNetApp();

        if (hkNetApp.init() && hkNetApp.login()) {
            Float temperature = hkNetApp.getTemperature(new HKPoint(1,1), 126, 100);
            log.info("1,1點(diǎn)的溫度是,{}", temperature);
        }

        hkNetApp.logout();
        hCNetSDK.NET_DVR_Cleanup();
    }

    /**
     * SDK初始化
     * @return
     */
    public Boolean init() {
        if (!hCNetSDK.NET_DVR_Init()) {
            log.error("初始化失敗");
            return false;
        }
        return true;
    }


    /*************************************************
     函數(shù):      "注冊(cè)"  按鈕單擊響應(yīng)函數(shù)
     函數(shù)描述:  注冊(cè)登錄設(shè)備
     *************************************************/
    public Boolean login() {//GEN-FIRST:event_jButtonLoginActionPerformed
        //注冊(cè)之前先注銷已注冊(cè)的用戶,預(yù)覽情況下不可注銷
        if (lUserID.longValue() > -1) {
            //先注銷
            hCNetSDK.NET_DVR_Logout_V30(lUserID);
        }
        //注冊(cè)
        m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V30();

        lUserID = hCNetSDK.NET_DVR_Login_V30("192.168.8.14", (short) 8000, "admin", "a1234567", m_strDeviceInfo);

        long userID = lUserID.longValue();
        boolean initSuc = hCNetSDK.NET_DVR_SetLogToFile(3, "f:\\sdklog\\", false);

        if (userID == -1) {
            log.error("登錄失敗,{}", userID);
            return false;
        }
        return true;
    }

    public void logout() {
        hCNetSDK.NET_DVR_Logout_V30(lUserID);
    }

    public Float getTemperature(HKPoint hkPoint, int sourceWidth, int sourceHeight) {
        boolean bRet = false;
        int nErr = 0;
        int erro;
        HCNetSDK.NET_DVR_THERMOMETRY_PRESETINFO m_struThermometryInfo = new HCNetSDK.NET_DVR_THERMOMETRY_PRESETINFO();
        m_struThermometryInfo.dwSize = m_struThermometryInfo.size();

        HCNetSDK.NET_DVR_THERMOMETRY_COND m_struThermometryCond = new HCNetSDK.NET_DVR_THERMOMETRY_COND();
        m_struThermometryCond.dwSize = m_struThermometryCond.size();
        m_struThermometryCond.dwChannel = 1;
        m_struThermometryCond.wPresetNo = 1;
        m_struThermometryCond.write();

        HCNetSDK.NET_DVR_STD_CONFIG struCfg = new HCNetSDK.NET_DVR_STD_CONFIG();
        struCfg.lpCondBuffer = m_struThermometryCond.getPointer();
        struCfg.dwCondSize = m_struThermometryCond.size();
        struCfg.lpOutBuffer = m_struThermometryInfo.getPointer();
        struCfg.dwOutSize = m_struThermometryInfo.size();

        HCNetSDK.BYTE_ARRAY m_szStatusBuf = new HCNetSDK.BYTE_ARRAY(4096 * 4);
        struCfg.lpStatusBuffer = m_szStatusBuf.getPointer();
        struCfg.dwStatusSize = 4096 * 4;
        struCfg.byDataType = 0;

        bRet = hCNetSDK.NET_DVR_GetSTDConfig(lUserID, 3624, struCfg);
        if (!bRet) {
            nErr = hCNetSDK.NET_DVR_GetLastError();
            log.error("NET_DVR_GetSTDConfig失敗,{}", nErr);
            return 0f;
        }

        m_struThermometryInfo.dwSize = m_struThermometryInfo.size();
        m_struThermometryInfo.wPresetNo = 1;
        m_struThermometryInfo.struPresetInfo[0] = new HCNetSDK.NET_DVR_THERMOMETRY_PRESETINFO_PARAM();
        m_struThermometryInfo.struPresetInfo[0].byEnabled = 1;
        m_struThermometryInfo.struPresetInfo[0].byRuleID = 1;
        m_struThermometryInfo.struPresetInfo[0].wDistance = 10;
        m_struThermometryInfo.struPresetInfo[0].fEmissivity = (float) 0.9599;
        m_struThermometryInfo.struPresetInfo[0].byReflectiveEnabled = 0;
        m_struThermometryInfo.struPresetInfo[0].fReflectiveTemperature = 20;
        m_struThermometryInfo.struPresetInfo[0].byRuleCalibType = 2;
        //m_struThermometryInfo.struPresetInfo[0].szRuleName ="1";
        m_struThermometryInfo.struPresetInfo[0].byDistanceUnit = 0;
        //m_struThermometryInfo.struPresetInfo[0].byemissivityMode = 0;
        m_struThermometryInfo.struPresetInfo[0].struPoint = new HCNetSDK.NET_VCA_POINT();
        m_struThermometryInfo.struPresetInfo[0].struPoint.fX = 0;
        m_struThermometryInfo.struPresetInfo[0].struPoint.fY = 0;
        m_struThermometryInfo.struPresetInfo[0].struPoint.write();
        m_struThermometryInfo.struPresetInfo[0].struRegion = new HCNetSDK.NET_VCA_POLYGON();
        m_struThermometryInfo.struPresetInfo[0].struRegion.dwPointNum = 2;
        m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[0] = new HCNetSDK.NET_VCA_POINT();
        m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[0].fX = (float) 0.187;
        m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[0].fY = (float) 0.6119;
        m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[0].write();
        m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[1] = new HCNetSDK.NET_VCA_POINT();
        m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[1].fX = (float) 0.876;
        m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[1].fY = (float) 0.569;
        m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[1].write();
        m_struThermometryInfo.struPresetInfo[0].struRegion.write();
        m_struThermometryInfo.write();
        struCfg.lpInBuffer = m_struThermometryInfo.getPointer();
        struCfg.dwInSize = m_struThermometryInfo.size();

        boolean setSTDConfig = hCNetSDK.NET_DVR_SetSTDConfig(lUserID, 3625, struCfg);
        log.info("NET_DVR_SetSTDConfig,{}", setSTDConfig);

        HCNetSDK.NET_DVR_JPEGPICTURE_WITH_APPENDDATA m_strJpegWithAppenData = new HCNetSDK.NET_DVR_JPEGPICTURE_WITH_APPENDDATA();
        m_strJpegWithAppenData.dwSize = m_strJpegWithAppenData.size();
        m_strJpegWithAppenData.dwChannel = 1;
        HCNetSDK.BYTE_ARRAY ptrJpegByte = new HCNetSDK.BYTE_ARRAY(2 * 1024 * 1024);
        HCNetSDK.BYTE_ARRAY ptrP2PDataByte = new HCNetSDK.BYTE_ARRAY(2 * 1024 * 1024);
        m_strJpegWithAppenData.pJpegPicBuff = ptrJpegByte.getPointer();
        m_strJpegWithAppenData.pP2PDataBuff = ptrP2PDataByte.getPointer();


        bRet = hCNetSDK.NET_DVR_CaptureJPEGPicture_WithAppendData(lUserID, 2, m_strJpegWithAppenData);
        if (bRet) {
            //測(cè)溫?cái)?shù)據(jù)
            if (m_strJpegWithAppenData.dwP2PDataLen > 0) {
                HKPoint point = point2point(hkPoint, sourceWidth, sourceHeight, m_strJpegWithAppenData.dwJpegPicWidth, m_strJpegWithAppenData.dwJpegPicHeight);
                return getTemperature0(m_strJpegWithAppenData.pP2PDataBuff.getByteBuffer( (m_strJpegWithAppenData.dwJpegPicWidth * point.y  + point.x) * 4, 4));
            }
        }

        return 0f;
    }

    private Float getTemperature0(ByteBuffer byteBuffer) {
        byte[] byTempData = new byte[4];
        byteBuffer.get(byTempData);

        int l = byTempData[0];
        l &= 0xff;
        l |= ((long) byTempData[1] << 8);
        l &= 0xffff;
        l |= ((long) byTempData[2] << 16);
        l &= 0xffffff;
        l |= ((long) byTempData[3] << 24);

        return Float.intBitsToFloat(l);
    }

    private HKPoint point2point(HKPoint points, int sourceWidth, int sourceHeight, int targetWidth, int targetHeight) {
        points.x = points.x * sourceWidth / targetWidth;
        points.y = points.y * sourceHeight / targetHeight;

        points.x = points.x >= targetWidth ? targetWidth : points.x;
        points.x = points.x < 0 ? 0 : points.x;

        points.y = points.y >= targetHeight ? targetHeight : points.y;
        points.y = points.y < 0 ? 0 : points.y;

        return points;
    }
}

sdk接口類亲桥,因?yàn)楣俜絛emo代碼較多這里只提取了需要使用的部分洛心。

import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.win32.StdCallLibrary;

import java.util.Arrays;
import java.util.List;

/**
 * 海康sdk調(diào)用接口
 */
public interface HCNetSDK extends StdCallLibrary {

    /**
     * 常量
     */
    int SERIALNO_LEN = 48;   //序列號(hào)長(zhǎng)度
    int NAME_LEN = 32;    //用戶名長(zhǎng)度

    //method
    boolean NET_DVR_Init();

    boolean NET_DVR_Cleanup();

    NativeLong NET_DVR_Login_V30(String sDVRIP, short wDVRPort, String sUserName, String sPassword, NET_DVR_DEVICEINFO_V30 lpDeviceInfo);

    boolean NET_DVR_Logout_V30(NativeLong lUserID);

    boolean NET_DVR_SetSTDConfig(NativeLong lUserID, int dwCommand, NET_DVR_STD_CONFIG lpInConfigParam);

    boolean NET_DVR_GetSTDConfig(NativeLong lUserID, int dwCommand, NET_DVR_STD_CONFIG lpOutConfigParam);

    boolean NET_DVR_CaptureJPEGPicture_WithAppendData(NativeLong lUserID, int lChannel, NET_DVR_JPEGPICTURE_WITH_APPENDDATA lpJpegWithAppend);

    int NET_DVR_GetLastError();

    //啟用日志文件寫(xiě)入接口
    boolean NET_DVR_SetLogToFile(int bLogEnable, String strLogDir, boolean bAutoDel);

    //NET_DVR_Login_V30()參數(shù)結(jié)構(gòu)
    class NET_DVR_DEVICEINFO_V30 extends Structure {
        public byte[] sSerialNumber = new byte[SERIALNO_LEN];  //序列號(hào)
        public byte byAlarmInPortNum;                //報(bào)警輸入個(gè)數(shù)
        public byte byAlarmOutPortNum;                //報(bào)警輸出個(gè)數(shù)
        public byte byDiskNum;                    //硬盤(pán)個(gè)數(shù)
        public byte byDVRType;                    //設(shè)備類型, 1:DVR 2:ATM DVR 3:DVS ......
        public byte byChanNum;                    //模擬通道個(gè)數(shù)
        public byte byStartChan;                    //起始通道號(hào),例如DVS-1,DVR - 1
        public byte byAudioChanNum;                //語(yǔ)音通道數(shù)
        public byte byIPChanNum;                    //最大數(shù)字通道個(gè)數(shù)
        public byte[] byRes1 = new byte[24];                    //保留
    }

    class NET_DVR_THERMOMETRY_PRESETINFO extends Structure {
        public int dwSize;//結(jié)構(gòu)體大小
        public short wPresetNo;//0-保留
        public byte[] byRes = new byte[2];
        public NET_DVR_THERMOMETRY_PRESETINFO_PARAM[] struPresetInfo = new NET_DVR_THERMOMETRY_PRESETINFO_PARAM[40];
    }

    class NET_DVR_THERMOMETRY_PRESETINFO_PARAM extends Structure {
        public byte byEnabled;  //是否使能:0- 否题篷,1- 是
        public byte byRuleID;//規(guī)則ID 0-表示無(wú)效词身,從1開(kāi)始 (list內(nèi)部判斷數(shù)據(jù)有效性)
        public short wDistance;//距離(m)[0, 10000]
        public float fEmissivity;//發(fā)射率(發(fā)射率 精確到小數(shù)點(diǎn)后兩位)[0.01, 1.00](即:物體向外輻射能量的本領(lǐng))
        public byte byDistanceUnit;//距離單位: 0-米(m),1-英尺(feet),2-厘米(centimeter)
        public byte[] byRes = new byte[2];
        public byte byReflectiveEnabled;//反射溫度使能:0- 否番枚,1- 是
        public float fReflectiveTemperature;//反射溫度 精確到小數(shù)后2位
        public byte[] szRuleName = new byte[NAME_LEN/*32*/];//規(guī)則名稱
        public byte[] byRes1 = new byte[63];
        public byte byRuleCalibType;//規(guī)則標(biāo)定類型 0-點(diǎn)法严,1-框,2-線
        public NET_VCA_POINT struPoint;//點(diǎn)測(cè)溫坐標(biāo)(當(dāng)規(guī)則標(biāo)定類型為"點(diǎn)"的時(shí)候生效)
        public NET_VCA_POLYGON struRegion;//區(qū)域户辫、線(當(dāng)規(guī)則標(biāo)定類型為"框"或者"線"的時(shí)候生效)
    }

    class NET_VCA_POINT extends Structure {
        public float fX;                                // X軸坐標(biāo), 0.001~1
        public float fY;                                //Y軸坐標(biāo), 0.001~1
    }

    class NET_VCA_POLYGON extends Structure {
        public int dwPointNum;                                  //有效點(diǎn) 大于等于3渐夸,若是3點(diǎn)在一條線上認(rèn)為是無(wú)效區(qū)域,線交叉認(rèn)為是無(wú)效區(qū)域
        public NET_VCA_POINT[] struPos = new NET_VCA_POINT[10]; //多邊形邊界點(diǎn),最多十個(gè)
    }

    class NET_DVR_THERMOMETRY_COND extends Structure {
        public int dwSize;//結(jié)構(gòu)體大小
        public int dwChannel;
        public short wPresetNo;//0-保留
        public byte[] byRes = new byte[62];
    }

    class NET_DVR_STD_CONFIG extends Structure {
        public Pointer lpCondBuffer;        //[in]條件參數(shù)(結(jié)構(gòu)體格式),例如通道號(hào)等.可以為NULL
        public int dwCondSize;            //[in] lpCondBuffer指向的內(nèi)存大小
        public Pointer lpInBuffer;            //[in]輸入?yún)?shù)(結(jié)構(gòu)體格式),設(shè)置時(shí)不為NULL渔欢,獲取時(shí)為NULL
        public int dwInSize;            //[in] lpInBuffer指向的內(nèi)存大小
        public Pointer lpOutBuffer;        //[out]輸出參數(shù)(結(jié)構(gòu)體格式),獲取時(shí)不為NULL,設(shè)置時(shí)為NULL
        public int dwOutSize;            //[in] lpOutBuffer指向的內(nèi)存大小
        public Pointer lpStatusBuffer;        //[out]返回的狀態(tài)參數(shù)(XML格式),獲取成功時(shí)不會(huì)賦值,如果不需要,可以置NULL
        public int dwStatusSize;        //[in] lpStatusBuffer指向的內(nèi)存大小
        public Pointer lpXmlBuffer;    //[in/out]byDataType = 1時(shí)有效,xml格式數(shù)據(jù)
        public int dwXmlSize;      //[in/out]lpXmlBuffer指向的內(nèi)存大小,獲取時(shí)同時(shí)作為輸入和輸出參數(shù)墓塌,獲取成功后會(huì)修改會(huì)實(shí)際長(zhǎng)度,設(shè)置時(shí)表示實(shí)際長(zhǎng)度奥额,而不是整個(gè)內(nèi)存大小
        public byte byDataType;     //[in]輸入/輸出參數(shù)類型,0-使用結(jié)構(gòu)體類型lpInBuffer/lpOutBuffer有效,1-使用XML類型lpXmlBuffer有效
        public byte[] byRes = new byte[23];
    }

    class BYTE_ARRAY extends Structure {
        public byte[] byValue;

        public BYTE_ARRAY(int iLen) {
            byValue = new byte[iLen];
        }

        @Override
        protected List<String> getFieldOrder() {
            return Arrays.asList("byValue");
        }
    }

    //設(shè)備抓圖附加全屏測(cè)溫?cái)?shù)據(jù)結(jié)構(gòu)體
    class NET_DVR_JPEGPICTURE_WITH_APPENDDATA extends Structure {
        public int dwSize;
        public int dwChannel;//通道號(hào)
        public int dwJpegPicLen;//Jpeg圖片長(zhǎng)度
        public Pointer pJpegPicBuff;//Jpeg圖片指針
        public int dwJpegPicWidth;  // 圖像寬度
        public int dwJpegPicHeight;  //圖像高度
        public int dwP2PDataLen;//全屏測(cè)溫?cái)?shù)據(jù)長(zhǎng)度
        public Pointer pP2PDataBuff; //全屏測(cè)溫?cái)?shù)據(jù)指針
        public byte byIsFreezedata;//是否數(shù)據(jù)凍結(jié) 0-否 1-是
        public byte[] byRes = new byte[255];
    }
}

下面是運(yùn)行結(jié)果:


image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末苫幢,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子垫挨,更是在濱河造成了極大的恐慌韩肝,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件九榔,死亡現(xiàn)場(chǎng)離奇詭異哀峻,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)哲泊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)剩蟀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人切威,你說(shuō)我怎么就攤上這事育特。” “怎么了先朦?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵缰冤,是天一觀的道長(zhǎng)犬缨。 經(jīng)常有香客問(wèn)我,道長(zhǎng)棉浸,這世上最難降的妖魔是什么怀薛? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮涮拗,結(jié)果婚禮上乾戏,老公的妹妹穿的比我還像新娘。我一直安慰自己三热,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布三幻。 她就那樣靜靜地躺著就漾,像睡著了一般。 火紅的嫁衣襯著肌膚如雪念搬。 梳的紋絲不亂的頭發(fā)上抑堡,一...
    開(kāi)封第一講書(shū)人閱讀 51,554評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音朗徊,去河邊找鬼首妖。 笑死,一個(gè)胖子當(dāng)著我的面吹牛爷恳,可吹牛的內(nèi)容都是我干的有缆。 我是一名探鬼主播,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼温亲,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼棚壁!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起栈虚,我...
    開(kāi)封第一講書(shū)人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤袖外,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后魂务,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體曼验,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年粘姜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鬓照。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡相艇,死狀恐怖颖杏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情坛芽,我是刑警寧澤留储,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布翼抠,位于F島的核電站,受9級(jí)特大地震影響获讳,放射性物質(zhì)發(fā)生泄漏阴颖。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一丐膝、第九天 我趴在偏房一處隱蔽的房頂上張望量愧。 院中可真熱鬧,春花似錦帅矗、人聲如沸偎肃。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)累颂。三九已至,卻和暖如春凛俱,著一層夾襖步出監(jiān)牢的瞬間紊馏,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工蒲犬, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留朱监,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓原叮,卻偏偏與公主長(zhǎng)得像赫编,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子篇裁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容