Introduction
This tip shows you how to convert images to base64, then compress the resulting string using this code before sending it to the visitor's browser for decompressing and image rebuilding. This is originally from an article entitled "Text re-encoding for optimising storage capacity in the browser."
Background
While developing an iOS app that loaded PDFs into the WebView, I was looking for a way to speed up the transfer of data to the device, and minimize the storage used by the app.
Each page of the PDF was split into an image which was then base64-encoded into a string and sent to the device from the Web Service (written in VB.NET and C#). I came across the original implementation in JavaScript from Financial Times Labs and ported it to C# to use server-side.
Using the Code
This will take any string
(long ones are better) and compress it using method #2 described in the article. The snowman is prepended to the string
to indicate to the browser-side script that this string
needs to be decompressed.
This method can compress the string
to ~50% of its original size.
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace ftCompress
{
class Program
{
public static string CompressString(string s)
{
int intStringLength = s.Length;
if (intStringLength % 2 != 0) {
s += " ";
}
int intStr1, intStr2;
string strOut = "";
for (int i = 0; i < intStringLength; i += 2)
{
intStr1 = Char.ConvertToUtf32(s, i) * 256;
intStr2 = Char.ConvertToUtf32(s, i + 1);
strOut += Char.ConvertFromUtf32(intStr1 + intStr2);
}
return Convert.ToChar(9731) + strOut;
}
public static string DecompressString(string s)
{
if (s [0] != Convert.ToChar (9731)) {
return s;
}
int m, n;
string strOut = "";
for (int i = 1, l = s.Length; i < l; i++) {
n = Char.ConvertToUtf32 (s, i);
m = (int)Math.Floor ((decimal)n / 256);
strOut += (Char.ConvertFromUtf32 (m) +
Char.ConvertFromUtf32 (n % 256));
}
return strOut;
}
static void Main(string[] args)
{
string strNew = CompressString("Hello world!");
string js = "var strCompressed = '" + strNew + "';";
Console.WriteLine (strNew);
Console.WriteLine (DecompressString (strNew));
System.IO.File.WriteAllText(@"ft-compressedString.js", js);
}
}
}
Points of Interest
This is my first attempt at writing C#, and my first attempt at porting from one language to another. I'm sure there are better implementations and am happy to hear from anyone who actually implements this into a production system.
History
- 10/10/13: Updated based on comments; added decompression method
- 10/9/13: First version, written and tested in Visual Studio 2008 on Windows XP