2016-11-23

INTRODUCTION

To View a demo first, use the link to YouTube video at the bottom of the post.

QR Codes is a square image made up of two colours; normally
white as a background colour and black as the foreground colour. The image
represents a bitmap and can contain simple text limited to a short paragraph;
but it is more useful when it represents a url, or a business card etc. In
these cases, a QR Code Reader can read the encoded url and or business card and
launch the site or make a call, import the contact and so on, depending on your
QR code reading software. Most phones and Pads have QR Code scanners.

USAGE

I’ve developed the solution for an Agricultural University. They conduct a lot of experiments, in the field and labs and require a simple label against each plot or pot or whatever else it is. The aim is to carry a mobile devices with you, scan the QR Code, this would automatically direct to the related SharePoint page/list-item where you can find out more information or update findings and so on. The solution shown simply concentrates on the integration with SharePoint and is a nice complement to my Short Url stuff.

SOLUTION(S)

The solution is a SharePoint feature that extends a document
library allowing it to store a QR Code against the document. Here the technical
challenge isn’t the ability to generate the code (open-source library is used
for that), but rather how we can show these consistently across all pages,
through embedding them within the pages. The QR Code generation library used is
GMA.QrCodeNet.Encoding (http://qrcodenet.codeplex.com/) . I have used an
earlier version, but it has a more current version available of CodePlex.

Technical Details

The solution is developed using Visual Studio 2010. It uses the SharePoint extensions known as the CKSDev tool kit. These need to be installed inside Visual Studio. This solution will also work with SharePoint 2010 Standard/Enterprise or SharePoint Foundation 2010. The following diagram shows the solution within solution explorer.

In the solution the following are the key elements;

  1. Feature folder – This contains the details of the feature such as Title, Description, feature activation scope etc. The scope of QR codes is defined at the web level.
  2. Event Receiver – This contains the c# code to run event when a document is added or updated. It contains the code to generate the QR code, add it to a special images library and store it.
  3. Images Library – Stores the actual images.
  4. Custom field – A field of type image that can be added to any images library. This stores the url for the image and displays the associated image in display mode.

Activation

The QR code feature can be activated for any SharePoint site. This is done through ‘Manage site features’ – a link for this can be found on the ‘Site Settings’ page. The solution is deployed globally and is available in all site collections. The feature, available for each individual web, on activation, creates an images list on that web. QR codes can be generated for any documents library, and includes all libraries based on document library type such as site pages library, publishing pages library etc.

Once the feature is activated, the document library will not automatically start creating QR codes; instead the QRImages column needs to be manually added to a documents library. This can be done through ‘Document Library Settings’ page. Simply select ‘add column from existing’ and then add the QR Image column.

There is no visible command or buttons to generate QR codes; instead once a document library is setup as above, any modifications to a document metadata or the update of the document as well as upload of new document will start the process of generating a new QR code. You must manually refresh the list view page (if QR code is one of the visible column) to see the new image.

Feature Details

The following are a number of Elements files for various aspects of the feature;

<Feature xmlns="http://schemas.microsoft.com/sharepoint/" Description="Generates
QR Code for document libraries that have QRImage field added to them" Id="694ffa27-3094-4a63-8183-200cf35e0fd6" Scope="Web" Title="Harper-Adams
QR Codes Generation">

<ElementManifests>

<ElementManifest Location="QRImage\Elements.xml" />

<ElementManifest Location="EventReceiverGenerateQR\Elements.xml" />

<ElementManifest Location="QRCodeImages\Elements.xml" />

</ElementManifests>

</Feature>

 

The QRImage Field

This field needs to be added to any document library that requires QR Code.

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

<Field Type="URL"

DisplayName="QRImage"

Required="FALSE"

EnforceUniqueValues="FALSE"

ShowInEditForm="FALSE"

ShowInNewForm="FALSE"

ShowInViewForms="TRUE"

Indexed="FALSE"

Format="Image"

Group="Harper
Adams Columns"

ID="{f74bc8b8-6370-48bc-9ed2-d869b2a2ad0f}"

SourceID="{5c96e6a5-6239-4920-b496-592a4d541b15}"

StaticName="QRImage"

Name="QRImage" >

</Field>

</Elements>

 

The Images Library Instance

The following Images Library is created on feature activation

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

<ListInstance Title="QR
Code Images"

OnQuickLaunch="TRUE"

TemplateType="109"

FeatureId="00bfea71-52d4-45b3-b544-b1c71b620109"

Url="Lists/QRCodeImages"

Description="This
holds the QR code images">

</ListInstance>

</Elements>

The Event Receiver

When an item is added or updated, one of these is run.

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

<!-- Note Pages Library is 850,
but as the base type is Document Library - it should also fire for that as well
-->

<Receivers ListTemplateId="101">

<Receiver>

<Name>EventReceiverGenerateQRItemAdded</Name>

<Type>ItemAdded</Type>

<Assembly>$SharePoint.Project.AssemblyFullName

lt;/Assembly>

<Class>QRCodeLibraryEnhancements.EventReceiverGenerateQR.EventReceiverGenerateQR</Class>

<SequenceNumber>10000</SequenceNumber>

</Receiver>

<Receiver>

<Name>EventReceiverGenerateQRItemUpdated</Name>

<Type>ItemUpdated</Type>

<Assembly>$SharePoint.Project.AssemblyFullName


lt;/Assembly>

<Class>QRCodeLibraryEnhancements.EventReceiverGenerateQR.EventReceiverGenerateQR</Class>

<SequenceNumber>10000</SequenceNumber>

</Receiver>

<Receiver>

<Name>EventReceiverGenerateQRItemDeleted</Name>

<Type>ItemDeleted</Type>

<Assembly>$SharePoint.Project.AssemblyFullName


lt;/Assembly>

<Class>QRCodeLibraryEnhancements.EventReceiverGenerateQR.EventReceiverGenerateQR</Class>

<SequenceNumber>10000</SequenceNumber>

</Receiver>

 

</Receivers>

</Elements>
 

The Code

Most of the code sits within the Event Receivers. The following are the only items of interest.

private string
CreateAndSaveQRCode(Guid siteGuid, Guid
webGuid, string url, string
name)

{

QrEncoder qrEncoder = new
QrEncoder(ErrorCorrectionLevel.H);

QrCode qrCode = new
QrCode();

qrEncoder.TryEncode(url, out
qrCode);

 

Renderer renderer = new
Renderer(5, Brushes.Black, Brushes.White);

MemoryStream ms =
new MemoryStream();

renderer.WriteToStream(qrCode.Matrix,
ms,System.Drawing.Imaging.ImageFormat.Jpeg);

string
weburl = string.Empty;

SPSecurity.RunWithElevatedPrivileges(delegate()

{

using
(SPSite site = new SPSite(siteGuid))

using
(SPWeb web = site.OpenWeb(webGuid))

{

SPPictureLibrary pic =
(SPPictureLibrary)web.Lists["QR Code Images"];//Images
is the picture library name

SPFileCollection filecol =
pic.RootFolder.Files;//getting all the files which is in pictire library

filecol.Add(name + ".jpg", ms,
true);//uploading the files to picturte library

weburl = web.Url;

}

});

return 
weburl + "/Lists/QRCodeImages/" +
name + ".jpg";

}

 

Within the event receiver code, it is easy enough to get various Ids. Nonetheless I’ve added the important part below. Note that you must disable Event Firing when updating the same listitem to avoid an infinite loop.

SPListItem item = properties.ListItem;

 

if
(!item.Fields.ContainsField(IMAGE_FIELD))

return;

 

string url
= CreateAndSaveQRCode(properties.SiteId, properties.Web.ID, (string)item["EncodedAbsUrl"],
item.UniqueId.ToString());

 

SPFieldUrl urlField =
item.Fields.GetFieldByInternalName(IMAGE_FIELD) as
SPFieldUrl;

 

if
(item[urlField.Title] != null)

{

SPFieldUrlValue urlFieldValue =
urlField.GetFieldValue(item[urlField.Title].ToString()) as
SPFieldUrlValue;

urlFieldValue.Url = url;

urlFieldValue.Description = "QR
code image";

}

else

{

SPFieldUrlValue value = new
SPFieldUrlValue();

value.Description = "QR
code image";

value.Url = url;

item[IMAGE_FIELD] = value;

} 

base.EventFiringEnabled
= false;

item.SystemUpdate();

base.EventFiringEnabled = true;

 

Demo

The following short video (sorry, no sound) demos both Tiny Url and QR Codes. It has no editing etc. done to it, but otherwise it is pretty Okay.

About the author 

Qamar Zaman