Fast-performance approach to display base64 as Image - c#

I have a database, which stores images as Base64 strings.
My mission is to create a gallery with those images. As my weapon of choice I tried to use fancybox and I load images as <img src="data:image/jpg;base64, MY_BASE64"/>. It works but it has a huge impact on performance. I have to wait for ~2s until image loads. Is there any better approach to deal with this problem?

I would recommend you create a generic handler (ashx) to render your image. I'm assuming you're storing it as actual binary in the database, as there's no reason to store it as base64.
Making a generic handler to output the image gives the following benefits:
The client can load these images asynchronously (gives very good perceived performance)
The client can cache images (ETags and Last-Modified)
The internet service provider and proxies can cache images
Less data gets transmitted (sending raw binary is roughly 33% smaller than sending base64 text)
Better browser support (do all browsers support using base64?)
The client will only download images that are being viewed (fancybox)

Related

What's is th best way to manage pictures WP 8.1

Actually I'm developing an "social" app for my office and I'm wondering what's the best way to load or manage pictures. Each user has a profil picture and I would like to display it wherever I want, on the profil view, in the contacts list (little smaller) for example. When the user creates its profil, he picks up a picture from the picture library on his phone and it's send to server as base64 encoded string. The code that I've used to save the picked picture on the server (SQL Server 2012 database):
var reader = new DataReader(pictureStream.GetInputStreamAt(0));
byte[] bytes = new byte[pictureStream.Size];
await reader.LoadAsync((uint)pictureStream.Size);
reader.ReadBytes(bytes);
string bytesString = Convert.ToBase64String(bytes);
So here bytesString contains the base64 encoded picture to send on the server. Atually, I'm facing two problems.
First problem:
The base64 encoded string cannot be inserted to the database even if the column type is varchar(max). The string is cut in the table.
Second problem:
If I want to build the picture from bytesString decoding the base64 string, it takes so much time that it's not possible to work like that.
So I'm wondering how applications such Instagram or other picture specialized application are managing pictures so well... Does anyone could give me some advises to manage pictures through an app ? Thanks in advance !
Two ideas come to mind:
1. Store the images in a binary-type column
I haven't used SQL server very much, but I guess there is a binary column type in which you can just store the original bytes of the image.
2. Store the images in files instead of the database.
Another thing you can do is to simply store the images in files with names based on the users' IDs (i.e. user_15.png).
Other considerations
Is there any reason to encode/decode the bytes? Sending the original image seems like a better option to me.
How are you actually sending the encoded image bytes? From what I understand varchar(max) should be able to hold quite a lot of data. Are you sure the server receives the right data?
On the client (in the WP 8.1 app) you may want to cache the images, so that you wouldn't need to load them from the server every time.

when to resize an image?

I am building a online store for hand made jewelry. Of course there is a lot of high quality pictures that i need to show, first in small sizes and when a client clicks on the image, than redirect him to a page with a same image in high quality.
What is a better way:
on saving image save two images one in low quality and the second in original quality
or
onload image use Bitmap to lower the quality?
It depends.
Resizing on demand causes a heavier server load. When a lot of people are accessing the site this might be an issue.
Resizing on upload reduces this problem.
Resizing on your client using image processing software does usually produce the best quality with low file size.
The "normal" resize-functions in .NET is far away from that quality.
Also: Consider caching. The IIS offers everything to use this, perhaps in combination with an eTag.
I would resize them on upload/addition. I would also make sure to name them appropriately to their size, like gold_ring_640_480.jpg.
Then, should I need to change the size of the preview, I would add functionality to resize it lazily on demand if a required picture size does not exist.
Image_240p exists?
not: create
save _240p
use the image
You don't need to save all image size . For my all website, I get image on the fly depend on dimension that I need. When have a request with file size, I will create a resized image on disk. In the next time, with the same request, I just check:
if file already in browse cached, I will return the header mention that website just get image from cache.
if file not in browse cache, I will check that "the file already generate in disk". If the file is available, just return the file to response
if file not in browse cache and not in disk. I will generate it and return the file content.
For image caching you can see this reference :https://developers.google.com/speed/docs/best-practices/caching
For image resize on the fly by .net: you can refer to : http://www.codeproject.com/Articles/191424/Resizing-an-Image-On-The-Fly-using-NET

Print or visually represent encrypted data

I have a scenario that requires me to generate a printed page with encrypted data that can be scanned into our application later. Much like a barcode but encrypted.
The volume of text to be encrypted would be between 1KB to 10KB but could increase in the future. Most likely not above 1MB.
I develop document processing systems so I understand the dos and donts of printing. Scanning usually adds properties to printed pages such as skewing, rotation, artifacts, etc.
So the question is:
What is the best format to represent this amount of data visually? Not barcodes I'm assuming.
Whatever the format, real estate is crucial since we want to squeeze the data into a single A4 page. I'm thinking Base64 encoding with code-table compression could be a candidate? Any thoughts.
EDIT: It seems like barcodes are the only viable solution. The data is essentially a series of digits so I could use base 10 and then compress them to a code/index table before encrypting it. Or would using a higher base be wiser here?
My suggestion would be to make a C# program that takes your data, encrypts it, then runs it through a Base64 encoder. Then I would take the Base64 data and create QR code bitmaps from the data. I would then shrink the bitmaps so you can fit a lot on a page, then I would print pages of those QR codes. Later you can scan them in, enlarge each code and then read in the data. Finally, you'd have to Base64 decode it and then decrypt it!
Is the application online? If so, have you thought about storing the data securely (encrypted if you really want it that way) in a server, and on your page printing an access token (or simply a web reference) in the form of a QR code? Upon scanning the token your app could then retrieve the actual data from the server.
EDIT
While the above would give you the higher reliability and scalability, you could still store the data in QR codes directly on the page. You'd just need to encrypt into the alphanumeric space (using Base64 encoding) and store it as a series of QR codes; each can store around 3KB, so you'd get a lot of data on the page (as long as the page wasn't damaged).
High-Capacity Color Barcodes are 2D matrix codes that use colored "bars" (typically triangles) to encode data on printed pages. The Wikipedia article says they can store 3kB per square inch.
Obviously these require color printing and scanning hardware.
Unless you need to be able to run this completely offline from any internet or network access, I would suggest encrypting the text, hashing the encryption and storing the hash in a QR code. Getting a 2d bar or QR code to store a 64 or 128 bit hash should be easy enough, and reliable enough for scanning (as that's what they are designed for). Commercial QR scanners or software are available to make the scanning easy.
If you cannot have access to a common server between printing and scanning, then 2d barcodes are your only real option, and won't have the information density you want. You'd have a better chance storing it on RFID or a mini CD.

getting images out of mssql in C# using streams

I have a database which stores .png images as the sql "image" type. I have some code which retrieves these images as a byte[], and sends them to the page via the FileContentResult object in .Net. Performance is key in this application, and the images have to be retrieved and displayed as quickly as possible. My question is, can this operation be performed quicker by passing a byte stream from the database to the browser, and not at anytime storing the whole byte array in memory. If this is possible and worthwhile doing, how do I do it?
Here is the code I have so far:
// Get: /Image/Get/5
public FileResult Get(int id)
{
Response.Cache.SetExpires(DateTime.Now.AddSeconds(300));
Response.Cache.SetCacheability(HttpCacheability.Public);
Response.Cache.SetValidUntilExpires(true);
// Get full size image by PageId.
return base.File(page.getFullsizeImage(id), "image/png");
}
And
public byte[] getFullsizeImage(int pageId)
{
return (from t in tPage
// Filter on pageId.
where t.PageId == pageId
select t.Image).Single().ToArray();
}
Thanks for any help!
A nice question.
Reality is the code required to send the image as a stream is really minimal. It is just Response.Write~~~ byte array and setting the HTTP's content-type header which must be very fast.
Now you seem to need to open up your database to the world to get it done quicker. That, being probably possible using features that allow SQL server to serve HTTP/interact with IIS (long time ago I looked at it), not a good idea so I do not believe you should take that risk.
You are already using the caching so that is cool but files being large, cache gets purged frequently.
But one thing to do is to have a local File Cache on the IIS and if image is used, it is written to the file on teh web server and from then on (until maybe next day when this is cleared) this other URL (to the static asset) is returned so requests would not have to go through the ASP.NET layer. It is not a great idea but will achieve what you need with least risk.
Changing the linq from single to first should give you nicer SQL, if PageId is the primary key you can safely assume first and single will return the same result.
Edit: Based on your comments, I think you should consider using DeepZoom from microsoft. Essentially, what this allows you to do is generate a specialized image file on the server. When a user is browsing the image in full view, just the couple of million or so pixels that are displayed on the screen are sent to the browser via AJAX. Then when the user zooms in, the appropriate pixels for the zoom level and x and y axis are streamed out.
There is a DeepZoom Composer which can be accessed via the command line to generate these image files on demand and write them to a network share. Your users will be really impressed.
Take a look at this example. This is a massive image - Gigabytes. in about the middle of the image you will see some newspaper pages. You can zoom right in and read the articles.
End of Edit
Do you have to have images with a large file size? If they are only meant for displaying in the browser, they should be optimized for the web. All main image editing applications have this ability.
If you do need the large file size, then you could provide optimized images and then when the user clicks on the image, allow them to download the full file. They should expect this download to take some time.
In Photoshop, the task is "Save for web". There is a similarly named plugin for Gimp.
I know that this doesn't answer your direct question ("can this operation be performed quicker by passing a byte stream"), but it might help solve your problem.

Resize and Display image from server with ASP.NET

Got a question. I have images hosted on my server. I already know of the method when an image is uploaded to resize it and save, but I have another thought in mind.
I was wondering if there is a way to resize when the image is requested from the user. Not when it was uploaded by the user.
So for example a user goes to upload an image and I DO NOT RESIZE it and save another copy of the resized image. Instead, when the image is requested by the user via an ASP.NET img control/tag it would resize the image on the fly to display it and display it via the img tag/control.
Why would I want to do this?
To save on disk space. Most servers have a disk space limit, but not a server processing limit. So I would like to save on disk space and use the processing space instead.
EDIT: As a startup website its currently better that I save disk than saving processing time. I don't have much money for large amount of space at this moment. Hopefully it will change when the site launches.
Any ideas? Thanks guys and girls.
I assume you can 'control' the urls to the resized images, so for example the full-sized image might be referenced as <img src="uploads/myphoto.jpg"/> the thumbnail could be to an ASPX or ASHX like <img src="uploads/myphoto.jpg.ashx"/>?
This article on CodeProject - Dynamic Image Resize seems to have exactly the source code you are looking for (and although it's in VB, it shouldn't be hard to port if you're a C# person). Hope that helps.
Finally, I'd encourage you consider the various forms of caching (both using Http-Headers, to ensure the images are cached at the client or proxy whenever possible; and using built-in ASP.NET features to avoid unnecessary processing of the same images over-and-over).
Although you'll be saving disk-quota, you're effectively slowing down every other page/request... just a thought.
Dynamic image resizing has numerous advantages, the least of which is reduced disk space usage. However, it does need to be combined with a form of persistent caching, such as either Amazon CloudFront or a disk cache.
Dynamic image resizing gives you great agility on your web site, whereas pre-generating image variants locks you in, preventing the eventual changes you will have to make. When combined with caching, there is no run-time performance difference between the two.
The ImageResizer library offers disk caching, CloudFront caching, and correct memory and cache management. It's been constantly improved and maintained since 2007, and is quite bulletproof. It's running a few social networking sites as well, some having over a million images.
It's a time-tested, traffic-tested, and unit-tested library :) It's also extremely simple to use - you just add ?width=x&height=y to the query string. Functionality can be added via 20+ plugins, so you won't be weighed down by unused code and features.
The article mentioned by CraigD is inherently limited in its performance by the fact that it uses an HttpHandler instead of using an HttpModule - an HttpHandler cannot pass a request back to IIS native code for execution after the resized image is written to disk. It also doesn't adjust jpeg encoding properly or play well with the ASP.NET cache or URL authorization system. Although, I do have to admit - compared to most of the sample code I've seen, it violates far fewer of the image resizing pitfalls I've compiled.
I strongly suggest using the ImageResizer library. It's good code, I wrote it :) If you do end up using sample code or writing your own, please avoid these pitfalls!
You can create an implementation of IHttpHandler to respond to image requests, in that handler you can have code that loads the image from disk and transforms to it a size that is needed. You need to return the proper mime type with the response, and use the WriteBytes method (or something like it, I forgot the name). Also, you may look into content expiration headers, so that the image may not have to be loaded every time by the same client, but is instead cached.
You claim unlimited processing but limited disk space. Most of the time, even if they don't enforce a processing limit, as you have more customers, hits to your site, processing will be a worse bottleneck than storage space, and it will cost more to add more processing. Furthermore,
If you have large images, resized and compressed versions will occupy %10 of the space of the originals, even if you store a display and thumbnail version.
Else, just serve them and display them resized by browser, it will be faster.
It is not really actual resize of image, it is rather resize when you display an image, but i used with success just simple
<img src="myimage" height="height you want to give" width="width you want
to give" alt="" />
It is working every time.

Categories