Call an ASMX webservice from Java
This is by no means the most elegant way of doing this, and I’d actively encourage using better code, but this works, and you’re welcome to copy it.
It uses the Norwegian asmx car lookup service here; http://no.registreringsnummerapi.com/developers.html
import java.net.*;
import java.io.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import java.io.*;public class HelloWorld {
public static void main(String[] args) {
try{String host = “www.regcheck.org.uk”;
Socket socket = new Socket(host, 80);
// change yourusernamehere
String request = “GET http://www.regcheck.org.uk/api/reg.asmx/CheckNorway?RegistrationNumber=BS23162&username=yourusernamehere HTTP/1.0\r\n\r\n”;
OutputStream os = socket.getOutputStream();
os.write(request.getBytes());
os.flush();InputStream in = socket.getInputStream();
StringBuilder sb=new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String read;while((read=br.readLine()) != null) {
//System.out.println(read);
sb.append(read);
}br.close();
String strXml = sb.toString();
int intStart = strXml.indexOf(“<?xml”);
strXml = strXml.substring(intStart);
//System.out.print(strXml);
socket.close();DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
ByteArrayInputStream input = new ByteArrayInputStream(strXml.getBytes(“UTF-8”));
Document doc = builder.parse(input);
NodeList nList = doc.getElementsByTagName(“Description”);
Node nNode = nList.item(0);
System.out.print(nNode.getTextContent());
}
catch(Exception ex)
{
System.out.print(“Error”);
}}
}
Resizing App Preview videos using EasyWMV
iMovie is a simple and intuitive app for creating AppPreview videos, but, what’s really annoying is that it only creates appPreview videos compatible with 4 inch iPhone displays – Like the iPhone 5s ? – really old.
You really need to have videos for the iPhone 6s, and 6 Plus. But before you buy QuickTime Pro, here’s a free way.
EasyWMV’s demo version is limited to 1 minute of video, but that’s fine for App Previews, which are only 30 seconds anyway. Now, you need to fiddle with the settings.
For the iPhone 6 Plus (5.5 inch), I selected Custom size – 1080×1920.
Deselect “Preserve aspect ratio”
Drop the bit rate down below 1200kbps.

Now for the techy stuff, how I diagnosed this – I uploaded a video with the bit rate too high, and got a vague warning from iTunes Connect. I then looked in inspector for more details and saw this:
{
“statusCode” : 400,
“errorCodes” : [ “MOV_H264_LEVEL_TOO_HIGH”, “MOV_VIDEOCODEC_NOT_ACCEPTABLE_FOR_VIDEOTYPE” ],
“suggestionCode” : “MOV_RESAVE_LOWER_LEVEL”,
“nonLocalizedMessage” : “H264 Level is too high. Please refer to Apple’s documentation for appropriate levels.”,
“localizedMessage” : “The H264 Level is too high. Please refer to Apple’s documentation for appropriate formats.”
}
Which according to apple, this is the maximum specs:
| H.264 | ProRes 422 HQ only | Notes |
|---|---|---|
| Target Bit Rate | 10-12 Mbps | VBR ~220 Mbps |
And 12Mbps translates to 12000 Kbps
Then you get this a success in the trace once it works:
{
“responses” : [ {
“url” : “http://a364.phobos.apple.com/us/r30/VideoSource60/v4/0f/8d/42/0f8d42b0-c7a1-3bbc-0fd9-47e6ce27cd4b/pr_source.mp4?downloadKey=1450740609_4e0cd82c5efe91f96becf577bbc3cdc4”,
“token” : “VideoSource60/v4/0f/8d/42/0f8d42b0-c7a1-3bbc-0fd9-47e6ce27cd4b/pr_source.mp4”,
“groupToken” : {
“groupToken” : “VideoSource60/v4/0f/8d/42/0f8d42b0-c7a1-3bbc-0fd9-47e6ce27cd4b”,
“pool” : “VideoSource60”,
“syntaxVersion” : “HASH_MOUNT_UUID_GROUP”
},
“blobString” : “{\”token\”:\”VideoSource60/v4/0f/8d/42/0f8d42b0-c7a1-3bbc-0fd9-47e6ce27cd4b/pr_source.mp4\”,\”type\”:\”MZPurpleSoftwarePromoVideoFileType.SOURCE\”,\”originalFileName\”:\”App Preview webcam-1.mp4\”}”,
“descriptionDoc” : “<?xml version=\”1.0\” encoding=\”UTF-8\” standalone=\”no\”?><!–Generated by the FoghornLeghorn Quicktime MediaDescriptionGenerator, version 1.24–><!–File URL: \”\”–><movie xmlns:ma=\”http://beans.media.leghorn.jingle.apple.com\” codecs=\”avc1.6742C0, mp4a.40.2\” type=\”mpeg4\”><describer><ma:name>FoghornLeghorn MPEG-4 Parser</ma:name><ma:version>1.24</ma:version></describer><clock poster_time=\”0\” preview_duration=\”0\” preview_time=\”0\” time_scale=\”1000\” total_duration=\”22016\”/><tracks><video enabled=\”true\” index=\”0\” type=\”vide\”><track_id>1</track_id><language numeric=\”21956\”>und</language><alternate_group>0</alternate_group><matrix identity=\”true\”/><data_size units=\”bytes\”>2745711</data_size><duration milliseconds=\”21967\” track_duration=\”21967\” units=\”milliseconds\”>21967</duration><edit_list count=\”1\” empties=\”0\” normal_rate=\”true\”><edit_list_entry media_rate=\”1.0\” media_time=\”2\” track_duration=\”21967\”/></edit_list><sample_description_count>1</sample_description_count><duration_statistics mean_duration=\”1.0\” time_scale=\”30\” total_duration=\”659\” uniform=\”true\”/><user_data_atoms/><data_rate units=\”Kb/s\”>976.50415</data_rate><data_rate_statistics units=\”Kb/s\”><peak first_media_DTS=\”99\” last_media_DTS=\”99\”>2719</peak></data_rate_statistics><graphics_mode>copy</graphics_mode><codec name=\”H.264\” type=\”avc1.6742C0\”>avc1</codec><encoded_dimensions><width>1080</width><height>1920</height></encoded_dimensions><display_dimensions><width>1080</width><height>1920</height></display_dimensions><track_dimensions><width>1080</width><height>1920</height></track_dimensions><frame_rate_mode>CFR</frame_rate_mode><frame_rate>30.0</frame_rate><field_dominance>progressive</field_dominance><sample_description><avcC><profile>Baseline</profile><compatability>192</compatability><level>4.0</level><nal_units><picture_parameter_sets><pic_parameter_set entropy_coding_mode_flag=\”0\” pic_parameter_set_id=\”0\” seq_parameter_set_id=\”0\”/></picture_parameter_sets></nal_units><raw_avcc>0142C028FFE1001A6742C028D9004403C797C044000003000400000300F03C60C92001000468CB8CB2</raw_avcc></avcC></sample_description><maximum_sample_size>81858</maximum_sample_size></video><sound enabled=\”true\” index=\”1\” type=\”soun\”><track_id>2</track_id><language numeric=\”5575\”>eng</language><alternate_group>0</alternate_group><matrix identity=\”true\”/><data_size units=\”bytes\”>680375</data_size><duration milliseconds=\”22016\” track_duration=\”22016\” units=\”milliseconds\”>22016</duration><sample_description_count>1</sample_description_count><user_data_atoms/><data_rate units=\”Kb/s\”>241.43484</data_rate><codec name=\”aac \” type=\”mp4a.40.2\”>aac </codec><channel_layout name=\”Stereo (L R)\”><channel name=\”Left\”>L</channel><channel name=\”Right\”>R</channel></channel_layout><sample_rate units=\”kilohertz\”>48.0</sample_rate><bit_depth>16</bit_depth></sound></tracks><matrix identity=\”true\”/><itunes_metadata_atoms><itunes_metadata format=\”UTF-8\” type=\”©too\”>Lavf52.88.0</itunes_metadata></itunes_metadata_atoms><notifications><ma:notification code=\”mediaValidation.data\” level=\”INFO\”><ma:parameters><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.trackType\”>vide</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.dataFormat\”>avc1</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.vendor\”>????</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.temporalQuality\”>0</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.spatialQuality\”>0</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.width\”>1080</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.height\”>1920</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.hRes\”>72.0</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.vRes\”>72.0</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.frameCount\”>1</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.compressorName\”/><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.depth\”>24</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.version\”>1</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.profile\”>66</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.compatability\”>192</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.level\”>4.0</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.profileIdc\”>66</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.constraintSets\”>c0</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.levelIdc\”>40</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.seqParameterSetId\”>0</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.log2MaxFrameNum\”>4</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.picOrderCntType\”>2</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.log2MaxPicOrderCountLsb\”>0</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.deltaPictureAlwaysZero\”>false</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.offsetForNonrefPic\”>0</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.offsetForTopToBottomField\”>0</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.numRefFramesInPicorderCntCycle\”>0</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.numRefFrames\”>3</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.gapsInFrameNumValueAllowedFlag\”>false</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.picWidthInMbs\”>68</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.picHeightInMapUnits\”>120</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.frameMbsOnly\”>true</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.mbAdaptiveFrameField\”>false</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.direct8x8Inference\”>true</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.frameCrop.left\”>0</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.frameCrop.right\”>4</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.frameCrop.top\”>0</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.frameCrop.bottom\”>0</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.vui.aspectRatio\”>1:1</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.vui.videoSignalType.videoFormat\”>5</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.vui.videoSignalType.videoFullRange\”>false</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.vui.timeInfo.numUnitsInTick\”>1</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.vui.timeInfo.timeScale\”>60</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.vui.timeInfo.fixedFrameRate\”>false</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.vui.bitStreamRestriction.motionVectorsOverPicBoundaries\”>true</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.vui.bitStreamRestriction.maxBytesPerPicDenom\”>0</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.vui.bitStreamRestriction.maxBitsPerMbDenom\”>0</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.vui.bitStreamRestriction.log2MaxMvLengthHorizontal\”>11</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.vui.bitStreamRestriction.log2MaxMvLengthVertical\”>11</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.vui.bitStreamRestriction.maxNumReorderFrames\”>0</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.sps.0.vui.bitStreamRestriction.maxDecFrameBuffering\”>3</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.pps.0.ppsId\”>0</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.pps.0.spsId\”>0</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.pps.0.entropyCodingMode\”>false</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.pps.0.sliceGroupMapType\”>0</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.pps.0.bottomFieldPictureOrderInFramePresent\”>false</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.pps.0.numRefIdx10DefaultActive\”>3</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.pps.0.explicitWeightedPrediction\”>false</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.pps.0.weightedBiPredIdc\”>0</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.pps.0.chromaQpIndexOffset\”>1</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.pps.0.deblockingFilterControlPresent\”>true</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.pps.0.constrainedIntraPrediction\”>false</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.pps.0.redundantPicCountElementPresent\”>false</ma:entry><ma:entry key=\”moov.trak.1.mdia.minf.stbl.stsd.0.avcC.0.pps.0.transform8x8Mode\”>true</ma:entry><ma:entry key=\”moov.trak.2.mdia.minf.stbl.stsd.0.trackType\”>soun</ma:entry><ma:entry key=\”moov.trak.2.mdia.minf.stbl.stsd.0.dataFormat\”>mp4a</ma:entry><ma:entry key=\”moov.trak.2.mdia.minf.stbl.stsd.0.numChannels\”>2</ma:entry><ma:entry key=\”moov.trak.2.mdia.minf.stbl.stsd.0.compressionId\”>0</ma:entry><ma:entry key=\”moov.trak.2.mdia.minf.stbl.stsd.0.sampleRate\”>48000.0</ma:entry><ma:entry key=\”message\”>data</ma:entry></ma:parameters></ma:notification></notifications></movie>”
}
]
}
Get #ISO3166 Country code from #IP address in C#

Although an IP address can’t always pinpoint where a user is to the correct city, it’s pretty reliable way of getting the user’s country, and you can tailor the content for that user, i.e. show prices in GBP for UK users, and USD for USD users.
There are plenty of ways of doing this, and many services that provide this service, but this worked well for me in an ASP.NET MVC website
WebClient wc = new WebClient();
var strJson = wc.DownloadString(“http://ipinfo.io/” + Request.ServerVariables[“REMOTE_ADDR”]);
var ip = Newtonsoft.Json.Linq.JObject.Parse(strJson);
var country = ip[“country”].ToString();
WhitehatTwitterFollowers.com : a new way to boost your twitter presence

WhitehatTwitterFollowers.com is a website that gets you new twitter followers based on your chosen hashtags ; and it’s WhiteHat, which means that there’s nothing untoward about the service.
That means that it’s not a service that get’s you an instant following of 10,000 zombie twitter accounts that all seem to have random twitter handles, and come from Eblonia*, oh, and they all get cancelled by twitter after it discovers that they’ve been created by a bot.
What it does, is uses the Twitter API to automatically favourite hundreds of tweets based on your selected hashtags, and those “favourites”, get you noticed by the authors of the tweets, and we’ve seen ratios typical of 3 new followers per 100 favourites.
So, it’s not an instant win, but a slow burn. But that’s what Whitehat is all about. If you prefer the 10,000 zombie accounts, look elsewhere.
*No, Eblonia is not a real place, it’s actually a nod to Dilbert 🙂
Google Image Search No Longer Available
About 2 days ago, Google Image Search API was terminated, and attempts to call the API gives an error “No Longer Available”. There is a work around, using the Google Custom Search API, and here’s some code to do it using JQuery.
(You’ll need to get your own key, since it’s limited to 100 queries per day)
function GoogleImageSearch(searchTerm, callback)
{
var params = {};
params.q = searchTerm; // search text
params.num = 1; // integer value range between 1 to 10 including
params.start = 1; // integer value range between 1 to 101, it is like the offset
params.imgSize = “large”; // for image size
params.searchType = “image”; // compulsory
params.fileType = “jpg”; // you can leave these if extension does not matters you
params.key = “xxxxxxx”; // API_KEY got from https://console.developers.google.com/
params.cx = “xxxxxx”; // cx value is the custom search engine value got from https://cse.google.com/cse(if not created then create it).
$.get(“https://www.googleapis.com/customsearch/v1”,params,function(img){
console.log(img);
callback(img.items[0].link);
}).fail(function(y){
console.log(y);
});
}
Prerolled jqm themes #JQM #Themeroller
With the latest version of Jquery Mobile, the included themes have been made decidedly more bland, and the themes available for JQM are quite specialized, like the BlackBerry theme, NativeDroid, Flat UI etc., but if you just want something simple and attractive, here is a hack to show themes that other users have done on ThemeRoller,
Just go to the url – https://themeroller.jquerymobile.com/?ver=1.4.5&style_id=YYYYMMDD-NN
where YYYYMMDD is a date within the last 30 days, and N is a sequental number.
Most of them are un-styled, and a lot are quite ugly, but you might find a gem there,
https://themeroller.jquerymobile.com/?ver=1.4.5&style_id=20151124-15 – Cookie – colourful
https://themeroller.jquerymobile.com/?ver=1.4.5&style_id=20151124-11 – maroon
https://themeroller.jquerymobile.com/?ver=1.4.5&style_id=20151124-10 – blue green
https://themeroller.jquerymobile.com/?ver=1.4.5&style_id=20151123-10 – grey blue
https://themeroller.jquerymobile.com/?ver=1.4.5&style_id=20151123-14 – tourquize
https://themeroller.jquerymobile.com/?ver=1.4.5&style_id=20151123-15 – Grey green
https://themeroller.jquerymobile.com/?ver=1.4.5&style_id=20151123-17 – Grey cyan
https://themeroller.jquerymobile.com/?ver=1.4.5&style_id=20151123-19 – pink
https://themeroller.jquerymobile.com/?ver=1.4.5&style_id=20151123-2 – purple pink
https://themeroller.jquerymobile.com/?ver=1.4.5&style_id=20151122-10 – orange grey
https://themeroller.jquerymobile.com/?ver=1.4.5&style_id=20151122-12 – light green

Updating the font used throughout a #wp8 #app
Using a custom font is a nice design touch that helps a windows phone app stand out, by looking a little different. The Segoe font can be a bit boring…
So, the standard way this is done, is by adding the following into Application.Resources in App.xaml
<Style TargetType=”TextBlock”>
<Setter Property=”FontFamily” Value= “assets/fonts/whatever.ttf#whatever”/>
</Style><Style TargetType=”TextBox”>
<Setter Property=”FontFamily” Value= “assets/fonts/whatever.ttf#whatever”/>
</Style>
But, here’s another approach, using reflection, and page hooks, like used in a previous post:
https://blog.dotnetframework.org/2015/11/09/localise-datepicker-in-wp8-silverlighttoolkit-using-hooks/
So, from within CompleteInitializePhoneApplication, add the code
PhoneApplicationPage page = RootFrame.Content as PhoneApplicationPage;
FontChangeHook(page);
then, FontChangeHook method as follows;
public static void FontChangeHook(PhoneApplicationPage page)
{
LoopThroughControls(page, (ui => {
var type = ui.GetType();
var prop = type.GetProperty(“FontFamily”);
if (prop != null)
{
prop.SetValue(ui, new FontFamily(@”assets/fonts/whatever.ttf#whatever”));}
}));
}
Free OCR using C= #Webservice
Converting an image into text is a difficult job for a computer, hence the pervasive use of Captcha images, however, OCR (optical character recognition) is quite effective with printed text.
Here’s a free webservice provided by a9t9, it’s limited to 500 requests/day or 15000 requests/month per IP address. You can get more quota by emailing a9t9 – You provide it with a url with an image that contains text;
It returns it’s results in JSON, so the bulk of this code is really just to convert the response to a simple string.
[WebMethod]
public string Automatic(string imageUrl)
{
var wc = new WebClient();
wc.Headers[“Content-Type”] = “application/x-www-form-urlencoded”;
const string strUrl = “https://ocr.a9t9.com/api/Parse/Image”;
var strPostData = “apikey=helloworld”;
strPostData += “&url=” + HttpUtility.UrlEncode(imageUrl);
var strJson = wc.UploadString(strUrl, “POST”, strPostData);
var result = JavascriptDeserialize<A9T9>(strJson);
return result.ParsedResults.First().ParsedText;
}
And the json conversion;
/// <summary>
/// Converts a JSON string into an object of type T.
/// </summary>
/// <typeparam name=”T”></typeparam>
/// <param name=”json”>The JSON string.</param>
/// <returns></returns>
public static T JavascriptDeserialize<T>(string json)
{
var jsSerializer = new JavaScriptSerializer { MaxJsonLength = Int32.MaxValue };
return jsSerializer.Deserialize<T>(json);
}public class ParsedResult
{
public int FileParseExitCode { get; set; }
public string ParsedText { get; set; }
public string ErrorDetails { get; set; }
}public class A9T9
{
public List<ParsedResult> ParsedResults { get; set; }
public int OCRExitCode { get; set; }
public bool IsErroredOnProcessing { get; set; }
public object ErrorDetails { get; set; }
}
Free SMS New Zealand, new website launched today
Just launched today http://www.freesms.co.nz – a website for sending free SMS messages to New Zealand, so you can keep in contact with your Kiwi relatives that haven’t yet moved over to the world of Whatsapp / Skype / Facebook Messenger yet.
It’s powered by the great guys over at Fortumo – a great free-to-try PSMS system, zero setup fees, zero monthly cost, and massive coverage. You just can’t beat them!
Localise DatePicker in #WP8 #SilverlightToolkit using hooks
The Silverlight toolkit for Wndows phone is really handy to get up and running quickly with advanced functionality on a Windows Phone app, however, when you want to customize it, you find that you end up downloading the source, and tinkering with it directly, which is fine, since it’s an open source project. However, for a minor change, it would be nice to keep treating it as a black box.
This approach however, could therefore be used to access and modify the XAML of any control, even closed-source ones. Which could be useful for Syncfusion or Telerik controls too.
So, first, we modify app.xaml.cs to create our hook.
Comment out // RootFrame.Navigated -= CompleteInitializePhoneApplication; in CompleteInitializePhoneApplication, so that the method gets called on every page load, not just on first load.
Then check the current page like this
PhoneApplicationPage page = RootFrame.Content as PhoneApplicationPage;
var strPage = (sender as NavigationService).CurrentSource.ToString();
if (strPage.Contains(“DatePickerPage.xaml”)) UI.DatePickerHook(page);
Hopefully, you don’t have a page called DatePickerPage.xaml in your app!, but this will call UI.DatePickerHook when the datepicker is opened.
Now, for a helpful utility function, which I’ve called LoopThroughControls – which applies an action to every control on a page recursively as follows;
private static void LoopThroughControls(UIElement parent, Action<UIElement> modifier)
{
int count = VisualTreeHelper.GetChildrenCount(parent);
if (count > 0)
{
for (int i = 0; i < count; i++)
{
UIElement child = (UIElement)VisualTreeHelper.GetChild(parent, i);
modifier(child);
LoopThroughControls(child, modifier);
}
}
return;
Then the DatePickerHook function is defined as follows
public static void DatePickerHook(PhoneApplicationPage page)
{
// Somehow modify the text on the top of the page…
LoopThroughControls(page, (ui => {
var tb = ui as TextBlock;
if (tb != null && tb.Name == “HeaderTitle”)
{
tb.Text = “”;
}
}));
}
