2014年9月15日 星期一

Create Image form memory

最近在測試從網路上抓 Google map下來,但不知該怎把抓下來的圖轉成Kanzi可用的。

這個軟體目前資源很少呀,用的人不多,不像Unity3D,可以很簡單就做到。

跟網路的溝通我是用POCO這個library



 std::string url = URIinit();
 URI uri(url);
 std::string path(uri.getPathAndQuery());
 if (path.empty()) path = "/";

 HTTPClientSession session(uri.getHost(), uri.getPort());
 HTTPRequest request(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1);
 HTTPResponse response;
 session.sendRequest(request);
 std::istream &is = session.receiveResponse( response );


在Kanzi建立需要的資源:

 
 struct KzuResourceManager* resourceManager 
  = kzuUIDomainGetResourceManager(kzaApplicationGetUIDomain(application));

 struct KzcMemoryManager* memoryManager = kzcMemoryGetManager(resourceManager);
 struct KzcImage* image;
 struct KzuImageTexture* texture;

把拿到的stream轉成 char* buffer再轉成Kanzi 的stream格式。

 std::ostringstream oss( std::ios_base::binary);
 oss << is.rdbuf();
 std::string strConst = oss.str();
 int size = strConst.length();
 
 const char* buffer = strConst.c_str();
 

 kzsException error;
 struct KzcInputStream* outstrem;
 error = kzcInputStreamCreateFromMemory(memoryManager, (kzByte*)buffer, size,  KZC_IO_STREAM_ENDIANNESS_UNSPECIFIED, &outstrem);


再用Kanzi的load png的Api: kzcImageLoadPNG,因為我已經知道抓下來是png的格式,若是其它的,要用其它的函式。之前本來想直接用kzuImageTextureCreateFromMemory,這個函式,但發現抓下來的是png,在設定 KZU_TEXTURE_CHANNELS時會有問題,因為png用的是索引色,不是用R8G8B8這種格式,還要把抓下來的raw data做轉換。
 error = kzcImageLoadPNG(memoryManager, outstrem, false, &image);
 /* Create texture from image. */
 result = kzuImageTextureCreateFromImage(resourceManager, "Widget Texture", 
  image, KZU_TEXTURE_FILTER_BILINEAR, 
  KZU_TEXTURE_WRAP_REPEAT, 0.0f, 
  &texture);
 kzsErrorForward(result);
 struct KzuObjectNode* screenNode 
  = kzuScreenToObjectNode(kzaApplicationGetScreen(application));
 
 struct KzuObjectNode* plane = kzuObjectNodeGetRelative(screenNode, "#Plane");
 result = kzuObjectNodeSetResourceIDResourceProperty(plane, KZU_PROPERTY_TYPE_TEXTURE,  kzuImageTextureToResource(texture));
 kzsErrorForward(result);


如果是直接從file中讀取,也可以用這個方式。之前拿來debug用的。把從網路上抓下來的部分改成下面這段就可以
 std::fstream myfile("myfile.png", std::ios::in | std::ios::binary);
 std::filebuf* pbuf = myfile.rdbuf();
 std::size_t size = pbuf->pubseekoff (0,myfile.end,myfile.in);
 pbuf->pubseekpos (0,myfile.in);
 char* buffer=new char[size];
 // get file data
 pbuf->sgetn (buffer,size);
 myfile.close();


沒有留言 :

張貼留言