tag:blogger.com,1999:blog-11025113748741997422024-02-20T23:29:20.627-08:00Schibum BlogUnknownnoreply@blogger.comBlogger9125tag:blogger.com,1999:blog-1102511374874199742.post-15397503809799893202013-03-20T10:22:00.002-07:002013-03-21T08:11:28.515-07:00WebGL Image Processing or How to Get Consistent gl_FragCoord ValuesMy <a href="http://schibum.blogspot.de/2013/03/qr-code-scanner-for-firefoxos.html">QR Code Scanner for FirefoxOS</a> now uses WebGL to speed up image preprocessing.<br />
<br />
<br />
And this is how the preprocessed video stream looks like (requires Browser with WebGL + getUserMedia support):<br />
<br />
<iframe height="700px" scrolling="no" src="https://dl.dropbox.com/u/7490218/webgl_binarizer/binarizer.html" style="border: none;" width="100%">
</iframe>
<br />
<div>
I'ts running some multi-pass fragment shaders to estimate a threshold for each pixel and then applies it to the gray value. I'm using a simple quad as described in <a href="http://dev.opera.com/articles/view/webgl-post-processing/">this article</a>. When I tested my shaders on four different devices, I got a a different result on each of them. I tracked it down to the following issue. The xy-coordinate of gl_Fragcoord is handled differently on all of my devices. According to the <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/gl_FragCoord.xml">OpenGL specs</a>, gl_Fragcoord.xy is supposed to be (0.5, 0.5) for the lower-left pixel. However I've also observed values like (0.0, 0.0), (1.0, 1,0) or (0.0, 0.5) on my Android and FirefoxOS devices. When gl_Fragcoord is used to sample from a texture, this leads to slightly inconsistent results across devices.<br />
<br />
This might not be a big problem for a single-pass algorithm, but with multiple passes the error induced by this inconsistency can easily screw up the result completely. To work around this, I detect the device dependent glFragCoord offset and neutralize it. Therefore I render 10x10 canvas with the following fragment shader, that just puts gl_FragCoord.xy on the red/green channel:
</div>
<pre class="prettyprint">
void main() {
vec4 result = vec4(1.0);
result.rg = gl_FragCoord.xy / 10.0;
gl_FragColor = result;
}
</pre>
<div>
I read the values with readPixels():
<pre class="prettyprint">
function round(val) {
return Math.round(100 * val / 255) / 10;
}
var imgdata = new Uint8Array(4 * canvas.width * canvas.height);
gl.readPixels(0, 0, canvas.width, canvas.height, gl.RGBA,
gl.UNSIGNED_BYTE, imgdata);
var xOffset = imgdata[0];
var yOffset = imgdata[1];
// assume 0.1 steps.
var fragCoordOffset = [round(xOffset), round(yOffset)];
</pre>
And pass them to my subsequent shader calls. In my shaders I then use the following function instead of gl_FragCoord.xy:
<pre class="prettyprint">
// Fragment coordinate normalized to pixel centers eg: (0.5, 0.5) for bottom-left pixel.
vec2 getNormalizedFragCoord() {
return (gl_FragCoord.xy - fragCoordOffset) + 0.5;
}
</pre>
And voila: same results on all devices.
</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-1102511374874199742.post-19325060870184804972013-03-07T13:30:00.001-08:002013-03-08T02:32:30.117-08:00QR Code Scanner for FirefoxOSI just published a very first version of the <a href="https://marketplace.firefox.com/app/qr-code-scanner-1/">QR Code Scanner for FirefoxOS</a> that I've been working on lately. It's also available on <a href="http://ffosqr.w69b.com/">http://ffosqr.w69b.com/</a> (without offline support). The GUI is till pretty simple but it does the basic jobs. And this is how it looks like:<br />
<br />
<div style="text-align: center;">
<iframe allowfullscreen="" frameborder="0" height="360" src="http://www.youtube.com/embed/6GR1vPijrnE" width="480"></iframe>
</div>
<div style="text-align: center;">
<br /></div>
The App is <a href="http://angularjs.org/">AngularJS</a> powered, test-driven by <a href="http://testacular.github.com/">Testacular</a>, scaffolded with <a href="http://yeoman.io/">Yeoman</a> and built with <a href="http://gruntjs.com/">Grunt</a>. It uses a custom port of the <a href="https://code.google.com/p/zxing/">ZXing barcode processing library</a> together with <a href="https://github.com/Schibum/iconv.js">iconv.js</a> and <a href="https://github.com/Schibum/utf8.js">utf8.js</a> to decode QR Codes. To grab images, it uses the getUserMedia API if available and falls back a static image picker else. Currently <a href="https://play.google.com/store/apps/details?id=com.opera.browser&hl=en"><span id="goog_409927911"></span>Opera Mobile<span id="goog_409927912"></span></a> is the only Mobile Browser that supports getUserMedia (and only the presto version, the new webkit-based beta does not), but you can also try it with a recent Desktop Browser (Firefox 20+, or Chrome 21+).<br />
<br />
The captured images are transferred to a web worker where the real work happens. This works quite smooth, even with Opera on my Android-powered mobile devices. Though I could not test it on any low-end device yet.<br />
<br />
Besides obvious GUI improvements, in future versions I'll add support for more barcode types and speed up the detection by offloading some image prepossessing work to the GPU using WebGL.Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-1102511374874199742.post-75952832319891834512012-12-10T03:20:00.001-08:002014-02-27T09:05:41.974-08:00vGet - Download Videos Directly to your Android DeviceDid you ever want to watch a movie on a train trip with bad mobile connectivity on your mobile device? You would like to download the video to your device, but unfortunately it is only embedded in a site and there is no download link?<br />
If this is the point where you usually dig through the HTML source code of the site, extract the URL of the video file and use wget to download it to your desktop computer, <a href="https://play.google.com/store/apps/details?id=mb.videoget&feature=search_result#?t=W251bGwsMSwyLDEsIm1iLnZpZGVvZ2V0Il0.">vGet</a> might be a handy tool. It basically does the same thing directly on your Android device. No need to turn on your computer.<br />
<br />
It works as a minimalist web browser. But instead of playing videos directly, it offers you an option to download them. It works on all websites that use HTML5 videos, which is quite cool. It comes without any site-specific extraction logic.<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXr4uKP8csWzljLOERz0NOPcRCyvDpnKfiOm-1S2fnw7aHNbedHdzao8yn4AP5y_N6wRNZk6F0kGOdIiBA2XK7YRGaZaKPrLmwhZT6YccuPgolRCC93PHDUwm6Z5YPlQVjZpeN3a4xip-g/s1600/video_detected.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXr4uKP8csWzljLOERz0NOPcRCyvDpnKfiOm-1S2fnw7aHNbedHdzao8yn4AP5y_N6wRNZk6F0kGOdIiBA2XK7YRGaZaKPrLmwhZT6YccuPgolRCC93PHDUwm6Z5YPlQVjZpeN3a4xip-g/s400/video_detected.png" height="400" width="250" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
Unfortunately some sites still use Flash to play videos. As you probably know, Flash is no longer supported on recent versions of Android. Even on older Android versions,it actually never really worked well in my opinion. Today every non-ancient web browser has native video support, so from a technical perspective, there is no reason anymore to use Flash for playing videos at all. However, some some sites seem to know better and still use it. To deal with Flash-ancientness, vGet goes one step further and can even play Flash videos on many sites. It then offers to play them directly (stream) or download them.<br />
<br />
For streaming, a media player needs to be installed on your Android device. <a href="https://play.google.com/store/apps/details?id=org.videolan.vlc.betav7neon&feature=search_result#?t=W251bGwsMSwyLDEsIm9yZy52aWRlb2xhbi52bGMuYmV0YXY3bmVvbiJd">VLC</a> or <a href="https://play.google.com/store/apps/details?id=com.mxtech.videoplayer.ad&feature=search_result#?t=W251bGwsMSwyLDEsImNvbS5teHRlY2gudmlkZW9wbGF5ZXIuYWQiXQ..">MXPlayer</a> both do a good job.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgm1Km7BtPQ37ClYOXxj3zW3NCPRUY3YuvLjSj3LG2NsqWfic_Y08mig_YtR4ozm8SfkUzMKs9hZ8mHll-boXm4p1pb2EydFFlEs9jWcwVKn52DP7BD1V86oq4pvugR0anVyMpR9p6U9map/s1600/grab.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgm1Km7BtPQ37ClYOXxj3zW3NCPRUY3YuvLjSj3LG2NsqWfic_Y08mig_YtR4ozm8SfkUzMKs9hZ8mHll-boXm4p1pb2EydFFlEs9jWcwVKn52DP7BD1V86oq4pvugR0anVyMpR9p6U9map/s400/grab.png" height="400" width="250" /></a></div>
<br />
Tip: you don't need to browse to a site using vGet, but instead can send URLs to open with vGet from your regular web browser on your Android device. Just choose "Share -> vGet":<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitUcc1G7uvb_O4kDqJUcmIicY6-hJ31EDBBNQJlFj6ReELmyhhU49rkwR_Dhsm4z9S2V7l3BP-Ohsmz__uay8sNARPnIgahGfXI3FPj0-8njGCx1C0HU64So3rYzknQwebRRY7RXBKtKKL/s1600/share.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitUcc1G7uvb_O4kDqJUcmIicY6-hJ31EDBBNQJlFj6ReELmyhhU49rkwR_Dhsm4z9S2V7l3BP-Ohsmz__uay8sNARPnIgahGfXI3FPj0-8njGCx1C0HU64So3rYzknQwebRRY7RXBKtKKL/s320/share.png" height="304" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglxWLFjOm3EKax4oxfBKX3HVgojYarpvsfbATqjHzjLJajR-n40zQNzpaCZ9ayvq4rs2z-58fmU26kcWNttqwS0oaOWRULjDLu68GDYVAuOO4kh9jjXhnn_GVEllwNAGdID9re1WDNDmUv/s1600/share_via.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglxWLFjOm3EKax4oxfBKX3HVgojYarpvsfbATqjHzjLJajR-n40zQNzpaCZ9ayvq4rs2z-58fmU26kcWNttqwS0oaOWRULjDLu68GDYVAuOO4kh9jjXhnn_GVEllwNAGdID9re1WDNDmUv/s400/share_via.png" height="400" width="250" /></a></div>
<br />
<br />
<a href="https://play.google.com/store/apps/details?id=mb.videoget&feature=search_result#?t=W251bGwsMSwyLDEsIm1iLnZpZGVvZ2V0Il0.">vGet is available on Google Play</a>. If you experience any problems please <a href="http://vget.w69b.com/bugs">report them</a>. I hope you find it useful.Unknownnoreply@blogger.comtag:blogger.com,1999:blog-1102511374874199742.post-51582356372384818972011-11-15T03:29:00.001-08:002011-11-15T03:38:56.100-08:00Vim Clipboard Support on UbuntuIf recently wondered why clipboard doesn't work in vim on ubuntu (eg. "+y to copy to clipboard). It turned out, that the <i>vim</i> package doesn't ship with clipboard support enabled:<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghL2p_m4ws0G9C5hXQ6eA0AySXPMEAKz801Xxc32QwIMdWrOw3UOthjJKrfmQwJOIMeVF9dD87rJ-4KRXIPTakURP_vsUyMdvg5yHaa8niDGVX2uN2lLp2S7BZAIw-l0wZ-EwFC4tjFUWu/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> vim --version | grep clipboard
-clientserver <b>-clipboard</b> +cmdline_compl +cmdline_hist +cmdline_info +comments
<b>-xterm_clipboard</b> -xterm_save
</code></pre>
<br />
You need to install <i>vim-gui-common</i> to get clipboard support:<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghL2p_m4ws0G9C5hXQ6eA0AySXPMEAKz801Xxc32QwIMdWrOw3UOthjJKrfmQwJOIMeVF9dD87rJ-4KRXIPTakURP_vsUyMdvg5yHaa8niDGVX2uN2lLp2S7BZAIw-l0wZ-EwFC4tjFUWu/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> vim --version | grep clipboard
+clientserver <b>+clipboard</b> +cmdline_compl +cmdline_hist +cmdline_info +comments
+xsmp_interact <b>+xterm_clipboard</b> -xterm_save
</code></pre>
<br />
<br />Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-1102511374874199742.post-3711940009659103012011-11-02T15:49:00.000-07:002012-01-17T03:54:59.633-08:00Ubuntu oneiric on Samsung Series 7 - 700Z5A S03<div class="separator" style="clear: both; text-align: center;">
<br /></div>
I recently bought a new Samsung Series 7 Notebook (700Z5A S03) as my replacement for my old Dell Latitude. It ships with a 750 GB hard disk with "8 GB ExpressCache". I replaced the HD by a faster SSD. In order to replace the disk, one has to open the bottom part of the case. The inside looks like this:<br />
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-GIBJUnMUUwI/TrG3R4gR_TI/AAAAAAAALLg/2LL8fUCi4Uk/s1600/02.11.11+-+1" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="301" src="http://2.bp.blogspot.com/-GIBJUnMUUwI/TrG3R4gR_TI/AAAAAAAALLg/2LL8fUCi4Uk/s400/02.11.11+-+1" width="400" /></a></div>
<br />
<br />
My model came with a Hitachi 7K750-750 inside. That's a usual harddisk. The so called "8 GB ExpressCache" seems to be on the board itself and is still visible as a usual blockdevice on linux after replacing the orignal hard disk. It's identified by hdparm as "Model=SanDisk iSSD P4 8GB, FwRev=SSD 9.14". For an SSD it seems to be quite slow. I use it as a swap device.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code># hdparm -t /dev/sdb
/dev/sdb:
Timing buffered disk reads: 362 MB in 3.02 seconds = 119.98 MB/sec
</code></pre>
<br />
<br />
Ubuntu Oneiric runs out of the box on the Notebook - at least to some extend. The Hybrid Graphics cannot be used up to now due to lack of driver support. Some folks at <a href="http://linux-hybrid-graphics.blogspot.com/">http://linux-hybrid-graphics.blogspot.com/</a> are working on that. I also couldn't get the dedicated graphics card disabled by following <a href="https://help.ubuntu.com/community/HybridGraphics">various</a> <a href="http://linux-hybrid-graphics.blogspot.com/">instructions</a> on that topic. As soon as the radeon kernel module is loaded (which is required for vgaswitcheroo to be even available) the power consumption of the system is quite high. The lowest power consumption I could achieve so far was by blacklisting the radeon module via modprobe. Idle power consumption, reported by powertop, is about 20-21W. This seems to be quite high as on Windows a idle power consumption of about 15W <a href="http://www.notebookcheck.net/Review-Samsung-Serie-7-700Z5A-Notebook.65554.0.html">was reported.</a> This might come from the dedicated graphic, not being fully disabled by just unloading radeon.<br />
Also the touchpad identified as "PS/2 Elantech Touchpad" by xinput list is not working as a touchpad but just a normal mouse. This is quite annoying as there is no way to disable tab-click. I stuck with disabling/enabling the touchpad completely so far (xinput set-prop 14 132 0/1 on my device).<br />
<br />
The notebook unfortunately cannot be ordered without an operating system. It ships with a Windows 7 Pro DVD labelled "System Recovery Media". Despite the labelling, the DVD acts as a usual Windows installation DVD that can also be installed and activated on other systems (tested on a virtualbox). This at least makes it possible to sell it on Ebay - together with the license sticker from the bottom of the case that can easily be removed by steaming it a bit.<br />
<br />
<b>UPDATE:</b><br />
The Touchpad is supported in Kernel 3.2. Even three fingers are supported (can be used to move windows in unity). By default it's quite insensitive though, I had to use my thumb to get the cursor moving. Adding the following lines to /etc/X11/xorg.conf fixes this:<br />
<br />
<br />
<pre style="background-color: #eeeeee; border-bottom-color: rgb(153, 153, 153); border-bottom-style: dashed; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(153, 153, 153); border-left-style: dashed; border-left-width: 1px; border-right-color: rgb(153, 153, 153); border-right-style: dashed; border-right-width: 1px; border-top-color: rgb(153, 153, 153); border-top-style: dashed; border-top-width: 1px; overflow-x: auto; overflow-y: auto; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px; width: 653px;"><span style="font-size: 12px; line-height: 14px;">Section "InputClass"
Identifier "touchpad catchall"
Driver "synaptics"
MatchIsTouchpad "on"
MatchDevicePath "/dev/input/event*"
Option "FingerLow" "6"
Option "FingerHigh" "10"
#
# Option "VertScrollDelta" "10"
EndSection</span><span style="font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px;">
</span></pre>
<div>
<br /></div>
<div>
<code><br /></code></div>Unknownnoreply@blogger.com42tag:blogger.com,1999:blog-1102511374874199742.post-23487706368792822492011-10-22T07:00:00.000-07:002011-10-22T07:00:02.293-07:00PDF Mergy - HTML5 PDF Merge ToolI lately created a simple <a href="http://pdfmerge.w69b.com/">PDF Merge tool</a> that is now available online. It allows those who are not able or willing to use a command-line to quickly merge PDF files without the need of installing a bloated tool on their commputer.<br />
Files can be added and ordered using a drag and drop interface.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0meW_MfUhG5u46R4yjj8_nFcStwF6W3JSq18eZcLiw94ZW5w2rM3GvTMehUoLrNw16rAN0borKBDwqF3wKTsjwN62n6cwVgTkRsOBfWLX6MdZRrzHNMAMnGN4wfZsBdDtfz3xAmolsLc0/s1600/upload.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0meW_MfUhG5u46R4yjj8_nFcStwF6W3JSq18eZcLiw94ZW5w2rM3GvTMehUoLrNw16rAN0borKBDwqF3wKTsjwN62n6cwVgTkRsOBfWLX6MdZRrzHNMAMnGN4wfZsBdDtfz3xAmolsLc0/s320/upload.png" width="320" /></a></div><div class="separator" style="clear: both; text-align: center;"><br />
</div>The application is hosted on Google AppEngine, while the actual merging is done on Rackspace CloudServers. After running some benchmarks it turned out that Rackspace CloudServers are much better suited for these kind of Tasks than Amazon EC2 nodes. I'm using a GAE-backed REST queue to distribute merge jobs. To reduce unecessary polling I'm using <a href="http://schibum.blogspot.com/2011/06/using-google-appengine-channel-api-with.html">gae_channel</a> to push queue updates to workers. Using a message system like RabbitMQ would probably be superior but require to run and maintain an additional server - something that I wanted to avoid.<br />
This is the first time I'm using gae_channel on productive enviroment. We'll see if it works well....Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-1102511374874199742.post-31817205447481639762011-06-12T09:22:00.000-07:002011-06-12T09:27:46.820-07:00Using Google Appengine Channel API with a Python ClientFor a project, I needed a way to perform long-poll requests with GAE. Just using a normal connection doesn't work because of the 30-Seconds request limit GAE enforces. But starting with Version 1.4 Google released the <a href="http://code.google.com/appengine/docs/python/channel/overview.html">Google Appengine Channel API</a> which allows long-pull requests with a javascript client library.<br />
It's quite easy to use. create a channel: <br />
<code><br />
from google.appengine.api import channel<br />
token = channel.create_channel(chan_name)</code><br />
<br />
And start sending messages:<br />
<code><br />
channel.send_message(chan_name, msg)<br />
</code><br />
<br />
Unfortunately, there is neighter any non-javascript client library for use in desktop applications, nor is there any specifications of the protocol available. So I reverse-engineered the javascript-client and created a <a href="https://bitbucket.org/lohre/gae_channel/overview">python client implementation</a>. Feel free to use it. But be aware that although it seems to work quite well, it's not well tested yet. I've not yet used it on a real-world application. Be also aware that google could change the underlying protocol without any notice, which would obliviously break this library.<br />
<br />
Use it like this:<br />
<pre><code>import gae_channel
channel = gae_channel.Client(token='your channel token')
for msg in chan.messages():
print msg </code></pre><pre><code> </code></pre>Also have a look at /demo. There's a small demo client available.<br />
<br />
<pre><code>$ python receiver.py
Your channel name is: fWVwdXvNJP
now run in an other terminal:
python sender.py fWVwdXvNJP
I'm now listening for messages, dont close this terminal...
</code></pre><br />
Now in another terminal, run:<br />
<pre><code>$ python sender.py fWVwdXvNJP
Enter a message:test
</code></pre><br />
Now you'll see the message appearing in the first terminal.<br />
<br />
Download from <a href="https://bitbucket.org/lohre/gae_channel/overview">bitbucket.</a>Unknownnoreply@blogger.com9tag:blogger.com,1999:blog-1102511374874199742.post-59952039569004459472011-06-11T06:01:00.000-07:002011-06-11T06:01:16.160-07:00QR Code GeneratorLast weekend, I've created this <a href="http://www.the-qrcode-generator.com/">simple QR-Code Generator</a>. It was small just-for-fun project. It's not that I felt the world'd need another QR Code Generator. I was looking for a simple project to play a with Googles <a href="http://www.google.com/url?sa=t&source=web&cd=1&ved=0CBUQFjAA&url=http%3A%2F%2Fcode.google.com%2Fclosure%2Flibrary%2F&rct=j&q=closure%20library&ei=wl7zTeTpJJDRsgbU1OCgBg&usg=AFQjCNEjViYJbndaXKfkKF5YYo_WtHWuxg&sig2=6KXEt6URpzWw6JD65LRNiA&cad=rja">Closure Library</a> and <a href="http://code.google.com/closure/compiler/">Closure Compiler</a>, especially its option for <a href="http://code.google.com/closure/compiler/docs/api-tutorial3.html#better">Advanced Optimization</a>. It enables function inlining and dead code removal, which I think is a really cool feature for javascript libraries, as you hardly every use all the features such libraries provide. This means you javascript files will get unnecessarily big, even if you do use some code minifier like Yahoo YUI or Closure Compiler (without Advanced Optimization). <br />
<br />
In my case I get the following javascript file sizes:<br />
<ul><li>simple optimization: 251K (gzipped: 57K)</li>
<li>advanced optimization: 60K (gzipped: 22K)</li>
</ul>As far as I know jQuery unfortunately is not compatible with Advanced Optimization, though its documentation is mutch better.<br />
<br />
The QR-Code Generator itself offers functionality for encoding Text, URLs, phone numbers and SMS. It has an option for shortening URLs. Wherefore it makes use of the <a href="http://goo.gl/">goo.gl</a> URL Shortener API. QR-Code-Images are generated using Google Chart API. <br />
<br />
I've published a it as a WebApp on <a href="https://chrome.google.com/webstore/detail/gcmhlmapohffdglflokbgknlknnmogbb">Chrome Web Store</a>. That's also something I wanted to try out. Maybe even some people consider it useful.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-1102511374874199742.post-68426513545643967942011-06-11T05:18:00.000-07:002011-06-11T05:18:45.955-07:00New BlogI just created this blog. From now on, I'll publish some coding-related stuff here.Unknownnoreply@blogger.com0