{"id":503,"date":"2011-11-12T10:23:15","date_gmt":"2011-11-12T10:23:15","guid":{"rendered":"http:\/\/www.drmop.com\/?p=503"},"modified":"2011-11-12T10:28:05","modified_gmt":"2011-11-12T10:28:05","slug":"marmalade-sdk-tutorial-downloading-and-using-image-from-a-web-based-image-file","status":"publish","type":"post","link":"http:\/\/www.drmop.com\/index.php\/2011\/11\/12\/marmalade-sdk-tutorial-downloading-and-using-image-from-a-web-based-image-file\/","title":{"rendered":"Marmalade SDK Tutorial &#8211; Downloading and Using an Image from a Web Based Image File"},"content":{"rendered":"<p>This tutorial is part of the Marmalade SDK tutorials collection. To see the tutorials index\u00a0<a title=\"Marmalade SDK tutorials index\" href=\"http:\/\/www.drmop.com\/?page_id=91\">click here<\/a><\/p>\n<p>Unfortunately my brother rang me last night and asked me to have a few quick battles with him on World of Warcraft (I just can&#8217;t resist PvP) so as it happens, I forgot all about the time and missed publishing my next blog. In case you plaw Wow and you&#8217;re wondering I have Level 85 Mage, Warlock, Paladin and Druid!<\/p>\n<p>In our previous tutorial we added the ability to send and receive data to and from a web server. We also created a new file class that deals with local and remote file access, allowing us to download files from the web and use them in our game. We also briefly mentioned that we had updated the CIwGameImage class to support JPEG\u2019s and creation of images from memory based files. In this tutorial we are going to go into that a little more as well as show you how to use CIwGameFile and CIwGameImage to download and display images from the web inside your games and apps. If you just want the code to this tutorial then <a title=\"IwGame - Marmalade SDK Game Engine\" href=\"http:\/\/www.drmop.com\/wp-content\/uploads\/2011\/11\/IwGame_v0220.zip\" target=\"_self\">download it from here<\/a>.<\/p>\n<p>Imagine a situation whereby you can distribute your basic game without having to carry around any of its content, so no graphics, no audio, no level files etc. Whilst that may not be completely practical for some types of games it is for many others. Imagine your game running completely on dynamic content that lives on a server and you can modify it at any time, Your players will benefit greatly from new fresh content regularly. Well, this is all possible using the Marmalade SDK and IwGame (wow that sounded a bill salesy!)<\/p>\n<h2>IwGameImage Changes<\/h2>\n<p>Ok the first change we made was to add the ability to create a CIwGameImage image from a JPEG. This feature is unfortunately not supported by Marmalades image classes and missing out on JPEG compression for larger images is a bit of a pain. That said, Marmalade does provide access to LibJPG, allowing you to implement your own JPEG loader. However, seeing as we have already done the work for it, you may as well just rip the code straight out of IwGameImage.cpp.<\/p>\n<p>The main method that takes care of JPEG decompression is CIwGameImage::DecompressJPEG(). Note that this method will create a RGB888 image from the JPEG file, I will add support for conversion to different image pixel formats in a future release.<\/p>\n<p>The next change to CIwGameImage is the ability to create an image from a file that has already been loaded into memory. This is very useful if you want to cache the compressed versions of images in memory:<\/p>\n<p>bool CIwGameImage::Init(const char* name, void* memory_file, int memory_file_size, bool is_jpeg)<\/p>\n<p>name \u2013 The name you would like to assign to the file<br \/>\nmemory_file \u2013 A pointer to the memory based file<br \/>\nmemory_file_size \u2013 The size of the memory based file<br \/>\nis_jpeg \u2013 Determines if the memory based image file is a jpeg<\/p>\n<p>Note that future versions will not rely on is_jpeg and instead, the header data will be checked to determine file type.<\/p>\n<p>How to Create a CIwImage or CIw2DImage from a Memory Based File<\/p>\n<p>Ok, lets take a look how we create an image from a memory based file in the CIwGameImage::Init() method:<\/p>\n<pre>\r\n<blockquote>\r\nbool CIwGameImage::Init(const char* name, void* memory_file, int memory_file_size, bool is_jpeg)\r\n{\r\n    CIwGameFile file;\r\n    if (file.Open(memory_file, memory_file_size))\r\n    {\r\n        if (is_jpeg)\r\n        {\r\n            if (!DecompressJPEG((char*)memory_file, memory_file_size))\r\n                return false;\r\n        }\r\n        else\r\n        {\r\n            CIwImage image;\r\n            image.ReadFile(file.getFileHandle());\r\n            Image2D = Iw2DCreateImage(image);\r\n            Width = Image2D-&gt;GetWidth();\r\n            Height = Image2D-&gt;GetHeight();\r\n        }\r\n    }\r\n\r\n    State = CIwGameImage_State_Loaded;\r\n\r\n    return true;\r\n}<\/blockquote>\r\n<\/pre>\n<p>As you can see we create a CIwImage by calling CIwImage::ReadFile() passing in the file handle of the memory based file (to find out how to create a file from a memory buffer take a look at CIwGameFile::Open(void* memory_buffer, int memory_buffer_len)).<br \/>\nTo turn the CIwImage to a CIw2DImage we call Iw2DCreateImage() passing in the CIwImage.<\/p>\n<h2>How to Create a CIwImage or CIw2DImage from a Pixel Data<\/h2>\n<p>In our CIwGameImage::Init() method you will notice that if the image file is a jpeg then we call DecompressJPEG(). If you look towards the end of our DecompressJPEG() method you will notice that we create our CIwImage \/ CIw2DImage a slightly different way.<\/p>\n<p>Because we are manually loading and decompressing the pixel data within the JPEG image we are left with a memory buffer containing our raw uncompressed images pixels. Marmalade\u2019s usual create from file style image creation methods do not cover this, so instead we create the image ourselves from the pixel data like so:<\/p>\n<pre>\r\n<blockquote>\r\nCIwImage image;\r\nimage.SetFormat(CIwImage::RGB_888);\r\nimage.SetWidth(Width);\r\nimage.SetHeight(Height);\r\nimage.SetOwnedBuffers((uint8*)data, 0);\r\nImage2D = Iw2DCreateImage(image);<\/blockquote>\r\n<\/pre>\n<p>Basically we create a CIwImage, set its format and dimensions then tell it where our pixel data is using SetOwnedBuffers(). Like we did in the previous example, to turn the CIwImage into a CIw2DImage we call Iw2DCreateImage() passing in the CIwImage.<\/p>\n<h2>Creating an Image from a Web Based Image File<\/h2>\n<p>The new demo shows how to download an image file from the web and create an image from it then display that image as a sprite. Lets firstly take a look at how we download and create the image:<\/p>\n<pre>\r\n<blockquote>\r\n<span style=\"color: #008000;\">\/\/ Download an image file from the web<\/span>\r\nCIwGameFile* image_file = new CIwGameFile();\r\nimage_file-&gt;Open(\"http:\/\/www.battleballz.com\/bb_icon.gif\", false, true);\r\nimage_file-&gt;Close();\r\n\r\n<span style=\"color: #008000;\">\/\/ Create an image from the downloaded gif file<\/span>\r\nCIwGameImage* image = new CIwGameImage();\r\nif (image_file-&gt;isFileAvailable() &amp;&amp; image_file-&gt;getError() == CIwGameFile::ErrorNone)\r\n    image-&gt;Init(\"\", image_file-&gt;getContent(), image_file-&gt;getContentLength(), false);\r\ndelete image_file; <span style=\"color: #008000;\">\/\/ We are done with the image file so we can delete it<\/span><\/blockquote>\r\n<\/pre>\n<p>Now we will create a sprite to display our downloaded web image::<\/p>\n<pre>\r\n<blockquote>\r\n<span style=\"color: #008000;\">\/\/ Create a test sprite to display our downloaded gif<\/span>\r\nCIwGameBitmapSprite* test_sprite = new CIwGameBitmapSprite();\r\ntest_sprite-&gt;setImage(image);\r\ntest_sprite-&gt;setDestSize(image-&gt;getWidth(), image-&gt;getHeight());\r\ntest_sprite-&gt;setSrcRect(0, 0, image-&gt;getWidth(), image-&gt;getHeight());\r\ntest_sprite-&gt;setPosition(image-&gt;getWidth() \/ 2, image-&gt;getHeight() \/ 2);<\/blockquote>\r\n<\/pre>\n<p>And that\u2019s about all there is to it.<\/p>\n<p>Some of you probably already have ideas buzzing around your heads on how to use this cool new system. I\u2019m going to put some more time into the image class this week because I\u2019m not happy about the way loading a jpeg and a web based image is different to the way we load images from a resource collection. I want to change the CIwGameImage class to basically allow you to specify not just a resource name, but also local file names and remote file names.<\/p>\n<p>Well that\u2019s it for this blog, as usual you can <a title=\"IwGame Marmalade SDK Game Engine\" href=\"http:\/\/www.drmop.com\/wp-content\/uploads\/2011\/11\/IwGame_v0220.zip\" target=\"_self\">download the latest code from here<\/a><\/p>\n<p>Happy coding and don&#8217;t eat too much tuna!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial is part of the Marmalade SDK tutorials collection. To see the tutorials index\u00a0click here Unfortunately my brother rang me last night and asked me to have a few quick battles with him on World of Warcraft (I just can&#8217;t resist PvP) so as it happens, I forgot all about the time and missed [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,13,29,43,118,44,42,28,148,3,45,1],"tags":[131,199,200,729,718],"class_list":["post-503","post","type-post","status-publish","format-standard","hentry","category-airplay-sdk","category-android-app-development","category-blackberry-playbook","category-blackberry-playbook-app-development","category-c-programming","category-game-and-app-development","category-ios-app-development","category-marmalade-sdk","category-pocketeers-limited","category-programming","category-samsung-bada-development","category-uncategorized","tag-ciwgamebitmapsprite","tag-ciwgamefile","tag-ciwimage","tag-iwgame-engine","tag-marmalade-sdk"],"_links":{"self":[{"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/posts\/503","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/comments?post=503"}],"version-history":[{"count":3,"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/posts\/503\/revisions"}],"predecessor-version":[{"id":506,"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/posts\/503\/revisions\/506"}],"wp:attachment":[{"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/media?parent=503"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/categories?post=503"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/tags?post=503"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}