About Me

My photo
Northglenn, Colorado, United States
I'm primarily a BI Developer on the Microsoft stack. I do sometimes touch upon other Microsoft stacks ( web development, application development, and sql server development).

Tuesday, December 15, 2009

Converting XPS to Bitmap

One thing I had to do recently, for a SSRS report, was attach a 3 page pdf to a notice that is mailed out. Since, I can't just attach a pdf directly to the report, I figured I'll just take the images.

So, first thing I did was print the pdf to a XPS file. Now I just need to take that XPS file and convert it to some type of usable image that SSRS can recognize.

Found a solution on one of the MSDN message boards; however, I had to make some updates to it:

Code Snippet
  1. static public void SaveXpsPageToBitmap(string xpsFileName)
  2. {
  3.     DirectoryInfo di = new DirectoryInfo(xpsFileName);
  4.     XpsDocument xpsDoc = new XpsDocument(xpsFileName, System.IO.FileAccess.Read);
  5.     FixedDocumentSequence docSeq = xpsDoc.GetFixedDocumentSequence();
  6.  
  7.     //DocumentReferenceCollection drc = docSeq.References;
  8.     for (int i = 0; i < docSeq.DocumentPaginator.PageCount; i++)
  9.     {
  10.         DocumentPage docPage = docSeq.DocumentPaginator.GetPage(i);
  11.         BitmapImage bitmap = new BitmapImage();
  12.         RenderTargetBitmap renderTarget = new RenderTargetBitmap((int)docPage.Size.Width, (int)docPage.Size.Height, 96, 96, PixelFormats.Default);
  13.     
  14.         renderTarget.Render(docPage.Visual);
  15.  
  16.         BitmapEncoder encoder = new BmpBitmapEncoder();
  17.         encoder.Frames.Add(BitmapFrame.Create(renderTarget));
  18.  
  19.         FileStream pageOutStream = new FileStream(di.FullName.Substring(0,di.FullName.Length - 4) + "_Page_" + (i+1).ToString() + ".bmp", FileMode.Create, FileAccess.Write);
  20.         encoder.Save(pageOutStream);
  21.         pageOutStream.Close();
  22.     }
  23. }




So this program works nicely, only problem I currently have is that I have to convert these large size bitmaps (~5MB per page) to something more reasonable. Especially, since the SSRS deployment gives me a SOAP error because of the size. I'll probably just end up converting them to Jpeg later on.

Tuesday, December 01, 2009

Creating an Psion Tecklogix Scan Gun App

In 4 simple and easy to follow steps:

Step 1: Getting Psion Resources

You will have to register to get access to the page.
(https://teknet.psionteklogix.com/ptxCMS/Teknet.aspx?s=us&p=DevKits)

Download and install their "Mobile Devices SDK"


Step 2: Create Project

If you go to the "Smart Device" section, you will notices a "Psion Teklogix Device Project". This add the Psion TeklogixNet reference and also the PtxSdkCommon.dll in the root directory, which is a dependency when running your app on device.
















Step 3: Add Items to the Toolbar, if needed

Right-click on the Toolbar, and select Choose Items.
Browse to C:\Program Files\Psion Teklogix\Mobile Devices SDK V3.1\DotNet2 and select the PsionTeklogixNet.dll

This should add:




If not already done so, drag each of those items onto the form.

















The default app gives a good example, it uses the ScanCompleteEvent; which send in a string value representation of the barcode and places it text into a textbox for the user to see.








Step 4: Deploying
Code Snippet
  1. /* $Revision 1.1.1.1 */
  2. /* Copyright Psion Teklogix Inc. 2007 */
  3. /*
  4. * File: Form1.cs
  5. *
  6. * Description:
  7. * Implementation file for Form1 class in PtxApp1
  8. *
  9. */
  10. using System;
  11. using System.Collections;
  12. using System.Collections.Generic;
  13. using System.ComponentModel;
  14. using System.Data;
  15. using System.Drawing;
  16. using System.Runtime.InteropServices;
  17. using System.Text;
  18. using System.Windows.Forms;
  19. using PsionTeklogix.Barcode;
  20. using PsionTeklogix.Barcode.ScannerServices;
  21.  
  22. /*! <summary>
  23. Contains the class and functions related to PtxApp1 scanner application
  24. </summary>
  25. */
  26. namespace PtxApp1
  27. {
  28.     /*
  29.     * Form1
  30.     *
  31.     */
  32.     /// <summary>
  33.     /// The Form1 class generates the Graphical User Interface for PtxApp1.
  34.     /// </summary>
  35.     public partial class Form1 : Form
  36.     {
  37.         /*
  38.         * InitializeScanner
  39.         *
  40.         */
  41.         /// <summary>
  42.         /// Initialize components for PtxApp1.
  43.         /// </summary>
  44.         private void InitializeScanner()
  45.         {
  46.             scanner.Driver = scannerServicesDriver;
  47.             scanner.ScanCompleteEvent += new ScanCompleteEventHandler(scanner_ScanCompleteEvent);
  48.         }
  49.  
  50.         /*
  51.         * Form1
  52.         *
  53.         */
  54.         /// <summary>
  55.         /// Required for Windows Form designer support.
  56.         /// </summary>
  57.         public Form1()
  58.         {
  59.             try
  60.             {
  61.                 InitializeComponent();
  62.                 InitializeScanner();
  63.             }
  64.             catch (Exception ex)
  65.             {
  66.                 MessageBox.Show("Failed to initialize component: " + ex.ToString());
  67.                 this.Close();
  68.             }
  69.         }
  70.  
  71.         /*
  72.         * Button1_Click
  73.         *
  74.         */
  75.         /// <summary>
  76.         /// This method is called when the scan button is clicked and will scan the
  77.         /// barcode.
  78.         /// </summary>b
  79.         /// <param name="sender">
  80.         /// The calling object that represents the user that sent the message.
  81.         /// </param>
  82.         /// <param name="e">
  83.         /// Contains event data of the Scan Button control
  84.         /// </param>
  85.         private void button1_Click(object sender, EventArgs e)
  86.         {
  87.             try
  88.             {
  89.                 scanner.Scan();
  90.             }
  91.             catch (Exception ex)
  92.             {
  93.                 MessageBox.Show("Scan error: " + ex.ToString());
  94.                 this.Close();
  95.             }
  96.         }
  97.        
  98.         /*
  99.         * Scanner1_ScanCompleteEvent
  100.         *
  101.         */
  102.         /// <summary>
  103.         /// This method is called when the scan complete event occurs. The method is
  104.         /// called by its respective handler and then displays a text representation
  105.         /// of the barcode on the display.
  106.         /// </summary>
  107.         /// <param name="sender">
  108.         /// The calling object that represents the user that sent the message.
  109.         /// </param>
  110.         /// <param name="e">
  111.         /// Contains event data once the scan is complete
  112.         /// </param>
  113.         delegate void scanner_ScanCompleteDelegate(object sender, ScanCompleteEventArgs e);
  114.  
  115.         private void scanner_ScanCompleteEvent(object sender, ScanCompleteEventArgs e)
  116.         {
  117.             if (!InvokeRequired)
  118.             {
  119.                 textBox1.Text = e.Text;
  120.             }
  121.             else
  122.             {
  123.                 Invoke(new scanner_ScanCompleteDelegate(scanner_ScanCompleteEvent),
  124.                 new object[] { sender, e });
  125.             }
  126.         }
  127.     }
  128. }
When deploying, remember to set the device to PtxPxa27c: ARMV4I_Release


P.S.
The size of the form shouldn't be bigger than 245 x 300

Friday, July 31, 2009

Project Euler Problem 1 (C# vs F#)

The problem:

If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.

Find the sum of all the multiples of 3 or 5 below 1000.


C#

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Diagnostics;

namespace Euler

{

class Program

{

//Add all the natural numbers below one thousand that are multiples of 3 or 5.

//0.001 seconds

static void Main(string[] args)

{

Stopwatch sw = new Stopwatch();

sw.Start();

int total = 0;

for (int i = 1; i <>

{

if (i % 3 == 0 || i % 5 == 0)

{

total += i;

}

}

Console.WriteLine("Answer: " + total);

sw.Stop();

Console.WriteLine(sw.Elapsed);

Console.WriteLine(sw.ElapsedTicks);

Console.ReadLine();

}

}

}


The F# solution:

F#

#light

//0096404 milliseconds

open System.Diagnostics

let stopWatch = new Stopwatch()

stopWatch.Start()

printfn "%A" (List.sum(List.filter (fun n-> (n % 3) = 0 or (n % 5) = 0) [1 .. 999]))

stopWatch.Stop();

printfn "%A"stopWatch.Elapsed

printfn "%A"stopWatch.ElapsedTicks

open System

Console.ReadKey(true)




C# does it in

0.001 seconds

3606 ticks


F# does it in

0.0096404 seconds

24380 ticks


There is probably some more efficient way of doing the F#, this was however my first attempt at learning the language. Will have to see how it can do the more tougher problems.


Thursday, May 21, 2009

Link Server limited return row size from Informix

So I ran into the following error while trying to run a query.

"Maximum output rowsize (32767) exceeded"

The problem with this, was that I was using a SQL SERVER link server, called ETS, to an Informix database. The problem was that I could not limit the size on the "Notes", so basically I ended up using an exec and open query just to accomplish this task.



declare @Query varchar(max)

set @Query = N'select

wrkhdr.region_no,

notif.atten,

notif.dba,

notif.owner,

notif.addr1,

notif.addr2,

notif.city,

notif.state,

notif.country,

notif.postal_code,

notif.notif_id,

notif.notif_date,

notif.start_date,

notif.end_date,

wrkhdr.create_user,

wrkhdr.rid,

wrkhdr.license_no,

notif.license_status,

rtrim(CAST(notes.note as nvarchar(250)))

FROM

notification notif

join workq_hdr wrkhdr ON wrkhdr.workq_id = notif.workq_id

left join document_header ON document_header.filing_id = wrkhdr.filing_id

left join document_header_notes ON document_header.recno = document_header_notes.document_header_notes_id

left join notes ON document_header_notes.notes = notes.note_id

where notif.notif_id = ' + convert(varchar(30),@Parameter1)

set @Query = N'select * from openquery(ets2, ''' + REPLACE(@Query, '''', '''''') + ''')'

exec (@Query)

Thursday, January 08, 2009

Permutations. The nth permutation from an ordered set of permutations.

So, I was doing Euler 24 from Project Euler. I thought of an interesting way of find the nth permutation from a set. Here is my solution:

       
Code Snippet
  1. /*A permutation is an ordered arrangement of objects. For example, 3124 is one possible permutation of the
  2.         digits 1, 2, 3 and 4.
  3.         * If all of the permutations are listed numerically or alphabetically, we call it lexicographic order. The lexicographic permutations of 0, 1 and 2 are:
  4.         012   021   102   120   201   210
  5.         What is the millionth lexicographic permutation of the digits 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9?
  6.         */
  7.         //.01 seconds
  8.         static void Main(string[] args)
  9.         {
  10.             Stopwatch sw = new Stopwatch();
  11.             sw.Start();
  12.             int[] numbers = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
  13.             char[] letters = new char[] {'a','b','c','d','e','f','g','h','i','j'};
  14.             Console.WriteLine(findPermutationAtElement<int>(numbers, 999999));
  15.             Console.WriteLine(findPermutationAtElement<char>(letters, 999999));
  16.             sw.Stop();
  17.             Console.WriteLine(sw.Elapsed);
  18.             Console.ReadLine();
  19.         }
  20.         private static string findPermutationAtElement<T>(T[] numbers, int p)
  21.         {
  22.             string answer = "";
  23.             ulong totalPerms;
  24.             int position;
  25.             ulong section;
  26.             T[] temp;
  27.             int length = numbers.Length;
  28.             //make sure array is ordered
  29.             numbers = numbers.OrderBy(n => n).ToArray();
  30.             for (int i = 0; i < length; i++)
  31.             {
  32.                 //find number of permutations left
  33.                 totalPerms = factorial(numbers.Length);
  34.                 //find what section number will fall into
  35.                 section = totalPerms / (ulong)numbers.Length;
  36.                 //find whole number index
  37.                 position = p / (int)section;
  38.                 //change p to reflect sub array position
  39.                 p = p % (int)section;
  40.                 //put value at the end
  41.                 answer = answer.Insert(answer.Length, numbers.ElementAt(position).ToString());
  42.                 //remove element from array
  43.                 temp = new T[numbers.Length - 1];
  44.                 for (int j = 0; j < numbers.Length; j++)
  45.                 {
  46.                     if (j == position)
  47.                     {
  48.                     }
  49.                     else if (j > position)
  50.                     {
  51.                         temp[j - 1] = numbers[j];
  52.                     }
  53.                     else
  54.                     {
  55.                         temp[j] = numbers[j];
  56.                     }
  57.                 }
  58.                 numbers = temp;
  59.             }
  60.             return answer;
  61.         }
  62.         private static ulong factorial(int p)
  63.         {
  64.             if (p == 0)
  65.             {
  66.                 return 1;
  67.             }
  68.             return (ulong)p * factorial(p - 1);
  69.         }