2017-07-27 5 views
0

私は、tcpソケット上の光センサー(本質的にカメラ)から.bmpイメージを受け取る必要があるnode.jsアプリケーションを開発しています。このカメラは、設定に応じて手動トリガまたは連続(数フレーム/秒)モードで画像をポストします。node.js net.socketクライアントがビットマップ(.bmp)イメージを受信する

私は、理想的な解決策ではありませんが、net.socketsを使用して何かを動作させています。理想的ではないと私は言う。なぜなら、私は騒々しいイメージを、時には壊れたイメージを得ているし、時には一緒にイメージを欠いているからだ。私はそれがカメラではないことを知っています。画像を信頼性高く高精度で取得する.netソリューションが既に存在するからです。相違点は、.netソリューションがタイマーのセンサーをポーリングし、net.socketsが非同期イベントベースであることです。

カメラのファームウェアは、画像ごとに画像(バイト、幅、高さ、種類、バージョンなどのサイズ)を記述する64バイトのヘッダを投稿するように設計されています。ヘッダーの情報を使って、次に何が来るのか知っています。現時点では、カメラが画像を供給する方法を変える余裕はありません。将来的には、現在のファームウェアで何かが可能であることを証明します。

私はnode.jsを使いこなしており、より良いソリューションを探しています。最終的に私はAngularJSクライアントが表示するsocket.io上に受信した画像を投稿できるようにしたいと思います。今のところ、忠実度の高い画像を確実に取得し、ディスクに書き込むだけで十分です。 、高速で効率的かつ信頼性の高い方法でこれを行う方法のための任意の提案をいただければ幸いです

<!-- language: lang-js --> 
let net = require('net'); 
let fs = require('fs'); 
//let stream = require('stream'); //will likely need this 

let client = new net.Socket(); 

const IMAGE_HEADER_SIZE = 64; 
const IMAGE_PREFIX_SIZE = 16; 

let headerImageSizeBytes = 0; 
let headerImageFrameNumber = 0; 
let imageBytesNeeded = 0; 
let imageByteCount = 0; 
let bytesAvailable = 0; 
let bytesRead = 0; 

client.connect(32200, '192.168.0.20', function() // 2MP 
{ 
    //client.bufferSize = 100;  // Doesn't seem to work 
    client.setNoDelay(true); 
    console.log('connected'); 
}); 

client.on('data', function (buffer) { 

    // Do we have a header frame? 
    if (buffer.length == 64) { 
     // Process that header 
     console.log(bytesRead == 0 ? 
      "Acquiring next image" : 
      "Last Image Bytes read = " + bytesRead); 
     bytesRead = 0; 
     headerImageSizeBytes = 0; 

     // Parse the header (Don't need 1st 16 Prefix bytes at this time) 
     var offset = IMAGE_PREFIX_SIZE; 
     headerImageSizeBytes = buffer.readUInt32LE(offset += 4); 
     headerImageFrameNumber = buffer.readUInt32LE(offset += 4); 
     imageBytesNeeded = headerImageSizeBytes; 
     return; 
    } 

    // Collecting image bytes 
    bytesRead += buffer.length; 
    if (bytesRead > 0) { 
     imageByteCount = bytesRead; 

     // TODO: Eventually going to need base64 to render as HTML image via Socket.io 
     fs.appendFile('c:/temp/_IMG_FOLDER/image' 
      + headerImageFrameNumber + '.bmp', buffer, function (err) { 
      if (err) { 
       console.log(err.message); 
      } 
     }); 
     console.log("\t\t" + buffer.length); 
    } 
}); 

client.on('close', function() { 
    console.log('Connection closed'); 
}); 

は、ここで私は、現在の作業を持っているコードです。

あなたの気持ちが分かれば、画像をAngularJSクライアントに投稿して画像ソースとして表示する方法の例です。

おかげ

答えて

0

コミュニティからNARYのぞきので、私は、私は、ヘッダを処理して、記載された画像を撮影する状態に陥るために、ステートマシンを使用して思い付いた溶液で私の質問にお答えします。この解決策は、非常にまともな信頼性を有する高品質の画像を生成する(すなわち欠落した画像が少ない)。

'use strict';ステート・マシンを使用するために彼の提案のための私のIntertech同僚の@ryanharveyへ

let net = require('net'); 
let fs = require('fs'); 

let client = new net.Socket(); 

const IMAGE_HEADER_SIZE = 64; 
const IMAGE_PREFIX_SIZE = 16; 
const STATE_INIT = 0; 
const STATE_DATA = 1; 
let state = STATE_INIT; 
let imageData; 
let imageOffset = 0; 


let headerImageSizeBytes = 0; 
let headerImageFrameNumber = 0; 
let imageBytesNeeded = 0; 
let bytesRead = 0; 

client.connect(32200, '192.168.0.20', function() 
{ 
    client.setNoDelay(true); 
    console.log('connected'); 
}); 


client.on('data', function (buffer) { 
    switch (state) { 

    case STATE_INIT: 

     // Ideally we'd have a more robust test here, i.e. consider scenario 
     // where header and image data arrive in same buffer 
     if (buffer.length !== 64) { 
     console.error('unexpected data received (bytes: ' + buffer.length + ')'); 
     return; 
     } 

     console.log(bytesRead == 0 ? 
     "Acquiring next image" : 
     "Last Image Bytes read = " + bytesRead); 
     bytesRead = 0; 
     headerImageSizeBytes = 0; 

     // Parse the header (Don't need 1st 16 Prefix bytes at this time) 
     var offset = IMAGE_PREFIX_SIZE; 
     headerImageSizeBytes = buffer.readUInt32LE(offset += 4); 
     headerImageFrameNumber = buffer.readUInt32LE(offset += 4); 
     imageBytesNeeded = headerImageSizeBytes; 
     imageData = Buffer.alloc(imageBytesNeeded) 
     imageOffset = 0; 
     state = STATE_DATA; 
     break; 

    case STATE_DATA: 
     imageOffset += buffer.copy(imageData, imageOffset); 
     if (imageOffset >= imageBytesNeeded) { 
     fs.appendFile('c:/temp/_FTP_FOLDER/image' + headerImageFrameNumber + '.bmp', imageData, function (err) { 
      if (err) { 
      console.log(err.message); 
      } 
     }); 
     state = STATE_INIT; 
     } // else continue acquiring image until all bytes received 
     break; 
    } 
}); 

client.on('end', function() { 
    console.log('Transimission end'); 
}); 

client.on('close', function() { 
    console.log('Connection closed'); 
}); 

感謝。

関連する問題