How to save html2canvas image into System Folder in jquery - c#

I have a form with id="form1" inside this form i have a graph.Now i am using html2canvas to get the image of this form1.Here is my code..
<script type="text/javascript">
$(document).ready(function () {
$('#add_button').click(function () {
alert("hiii");
$('form1').html2canvas();
var queue = html2canvas.Parse();
var canvas = html2canvas.Renderer(queue, { elements: { length: 1} });
var img = canvas.toDataURL();
window.open(img);
alert("Hello");
});
});
</script>
<form id="form1" runat="server">
<div style="padding-left:150px">
<asp:Literal ID="FCLiteral1" runat="server"></asp:Literal>
</div>
<div style="padding-left:350px"><b>Demo</b></div>
</form>
<input type="submit" id="add_button" value="Take Screenshot Of Div" " />
So my question is how can i save this image into my system hardisk..Please help me.

System hardisk? I did not understand, server or client?
CLIENT
If you want the user to download the image automatically, you will need to modify the Data URI scheme
Try this:
Add in css
#myHideFrame {
position: absolute;
top: -9999px;
width: 1px;
height: 1px;
}
Add in Javascript
var img = canvas.toDataURL();
var frame = document.getElementById("myHideFrame");
if(!frame) {
frame = document.createElement("iframe");
frame.id = "myHideFrame";
document.body.appendChild(frame);
}
frame.src = img.replace(/^data[:]image\/(png|jpg|jpeg)[;]/i, "data:application/octet-stream;");
Unfortunately this example does not show the name, for this you will have to do something like this (user need click in link):
var img = canvas.toDataURL();
var link = document.createElement("a");
link.download = "photo.png"; //Setup name file
link.href = img.replace(/^data[:]image\/(png|jpg|jpeg)[;]/i, "data:application/octet-stream;");
document.body.appendChild(link);
SERVER
If you want to save on the server then you need to use Ajax, example with Jquery:
Javascript file:
var img = canvas.toDataURL().replace(/^data[:]image\/(png|jpg|jpeg)[;]base64,/i, "");
$.ajax({
"type": "POST",
"url": "upload.aspx/UploadImage",
"data": {
"imageData": img //Send to WebMethod
}
}).done(function(o) {
console.log(["Response:" , o]);
});
Your upload.aspx.cs file need:
...
[WebMethod()]
public static void UploadImage(string imageData)
{
string fileNameWitPath = "custom_name.png";
using (FileStream fs = new FileStream(fileNameWitPath, FileMode.Create))
{
using (BinaryWriter bw = new BinaryWriter(fs))
{
byte[] data = Convert.FromBase64String(imageData);//convert from base64
bw.Write(data);
bw.Close();
}
}
}
...
See details: http://www.dotnetfunda.com/articles/show/1662/saving-html-5-canvas-as-image-on-the-server-using-aspnet

A much simpler solution to save an image on the Client side will be to generate an image data and append it to the <a> tag with download attribute on it.
Here is my example:
HTML:
<a href="#" class="downloadAsImage hide" download>Download</a>
JS:
$(function() {
html2canvas($('.main'), {
onrendered: function(canvas) {
$('.downloadAsImage').attr('href', canvas.toDataURL()).removeClass('hide');
}
});
});
Side note: bare in mind that you can't click $('.downloadAsImage') via JS as it has download attribute on it.

Related

Force Controller Action to return "Type" as Image and NOT as document

Basically, my view is trying to display both thumbnail image and full size image:
<img src="/Images/GetImage/60?s=1&t=True" class="" style="width: 100px; height: 80px;" data-id="60" data-source="1">
<img src="/Images/GetImage/60?s=1&t=False" class="" style="width: 100px; height: 80px;" data-id="60" data-source="1">
The only thing that changes is the t (thumbnail) boolean value.
When I pass true, the browser http request is interpreted as Type: jpeg
When I pass false, it is interpreted as document
Please check the following printscreen:
How can I really force the Controller Action to return Type as Image and NOT as document?
My actual source code:
public async Task<ActionResult> GetImage(int id, EnumImageSource s, bool t)
{
var backupImagePath = Server.MapPath(Url.Content("~/Content/Images/PhotoNotAvailable.png"));
var originalImagePath = Server.MapPath(Url.Content("~/Content/Images/PhotoNotAvailable.png"));
var finalImagePath = Server.MapPath(Url.Content("~/Content/Images/PhotoNotAvailable.png"));
...
...
...
...
if (model != null)
{
...
...
...
originalImagePath = model.Object.Path;
}
if (t)
{
var extension = System.IO.Path.GetExtension(originalImagePath);
var thumbImagePath = System.IO.Path.ChangeExtension(originalImagePath, null) + "_thumb" + extension;
if (System.IO.File.Exists(thumbImagePath))
{
finalImagePath = thumbImagePath;
}
else
{
if (System.IO.File.Exists(originalImagePath))
{
int width;
int height;
if (ProcessImage.GetDimentionsByImageType(EnumImageSize.Thumbnail, out width, out height))
{
try
{
if (ProcessImage.ResizeImageFile(width, height, originalImagePath, thumbImagePath))
{
finalImagePath = thumbImagePath;
}
}
catch
{
}
}
}
}
}
else
{
if (System.IO.File.Exists(originalImagePath))
{
finalImagePath = originalImagePath;
}
}
var bytes = System.IO.File.ReadAllBytes(finalImagePath);
Response.ContentType = "image/jpeg";
return File(bytes, "image/jpeg");
}
UPDATE #1
As requested by MaKCbIMKo. Yes, if I display the full image next to the thumbnail then both of them are processed as "Image".... but as you can see the way that I am add the "a" html tag is using the same path... however, now it seems that the lightcase.js is somehow processing it as document and not as image, probably by trying to read the "path extension" and match it with image or not... I really think this is the problem now.
<div class="img-wrap">
#if (Model.IsReadOnly == false)
{
<span class="close">×</span>
}
<a href="#(Url.Action("GetImage", "Images", new { area = "", id = i.Id, s = (int)i.ImageSource, t = false }))" data-rel="lightcase:myCollection#(Model.SourceId)" class="showcase">
<img src="#(Url.Action("GetImage", "Images", new {area = "", id = i.Id, s = (int) i.ImageSource, t = true}))" class="" style="width: 100px; height: 80px;" data-id="#i.Id" data-source="#((int)Model.ImageSource)" />
</a>
FULL IMAGE
<img src="#(Url.Action("GetImage", "Images", new {area = "", id = i.Id, s = (int) i.ImageSource, t = false}))" class="" style="width: 100px; height: 80px;" data-id="#i.Id" data-source="#((int)Model.ImageSource)" />
</div>
It seems that the problem was the lightcase.js code....
I just tested a quick change on the source code:
createObject: function () {
var $object;
// Create object
switch (_self.objectData.type) {
....
default:
$object = $(new Image());
$object.attr({
// The time expression is required to prevent the binding of an image load
'src': _self.objectData.url,
'alt': _self.objectData.title
});
break;
And now I have the image displayed as image and not inside the iframe....
This is not the final solution, but at least a proof to where the problem lies.
Ok, from here I know what I can do and on how to tackle this.
I noticed two things about lightcase.js:
-They always use link and not an image. Even if image is shown, it is inside <a> element. So, try to wrap your <img /> with <a>.
-They check urls for ending in some predefined extensions. Check source, from line 114 (typeMapping) and line 752 (_verifyDataType function). It might help if you add dummy query string parameter like:
Images/GetImage/60?s=1&t=True&type=.jpg. You will ignore it server side but might help with lightcase
I can't try it right now, but I hope it helps.
In the past I have had strange issues when returning files with ActionResult specially file encoding Try returning FileContentResult

Google map not properly load in web browser control

I have one html file like Map.Html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title></title>
<script type="text/javascript" src="http://maps.google.com.mx/maps/api/js?sensor=true"></script>
<script type="text/javascript">
var geocoder;
var map;
function initialize() {
geocoder = new google.maps.Geocoder();
var myOptions = {
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var address = "Ahmedabad, India" //change the address in order to search the google maps
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
var infoWindow = new google.maps.InfoWindow({
content: 'Hello'
});
google.maps.event.addListener(marker, "click", function (e) {
infoWindow.open(map, marker);
});
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
}
</script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="width:100%; height:100%"></div>
</body>
</html>
then i load this html file in webbrowser control DocumentText using below code:
using (StreamReader reader = new StreamReader(System.Windows.Forms.Application.StartupPath + "\\Map.html"))
{
_mapHTML = reader.ReadToEnd();
}
webBrowser1.DocumentText = _mapHTML;
but map not load properly.
zoom in/out, Map/Satellite option, Marker are showing but one white layer on map display.
SOLVED -- for me at least.
For some reason, the Webbrowser control is defaulting to a bad version (experimental?). I changed my initialization script to specify the current 3.3 version and everything is back to normal.
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3.3"></script>

bing map does not load

Im doing a web application in C# and ASP.NET MVC4.
Im having a problem with loading a map on one of my view pages...
I have the map on my Details page and the you go from Index page to Details page.
This is some of my code:
<div id='myMap' style="position:relative; width:400px; height:400px;">
</div>
<div>
<input type="button" value="createWalkingRoute" onclick="createDirections();" />
</div>
<div id='directionsItinerary'> </div>
#section scripts{
<script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0"></script>
<script type="text/javascript">
var map = null;
var directionsManager;
var directionsErrorEventObj;
var directionsUpdatedEventObj;
function getMap() {
map = new Microsoft.Maps.Map(document.getElementById('myMap'), { credentials: 'mykey' });
}
function createDirectionsManager() {
var displayMessage;
if (!directionsManager) {
directionsManager = new Microsoft.Maps.Directions.DirectionsManager(map);
displayMessage = 'Directions Module loaded\n';
displayMessage += 'Directions Manager loaded';
}
alert(displayMessage);
directionsManager.resetDirections();
directionsErrorEventObj = Microsoft.Maps.Events.addHandler(directionsManager, 'directionsError', function (arg) { alert(arg.message) });
directionsUpdatedEventObj = Microsoft.Maps.Events.addHandler(directionsManager, 'directionsUpdated', function () { alert('Directions updated') });
}
function createWalkingRoute() {
if (!directionsManager) { createDirectionsManager(); }
directionsManager.resetDirections();
// Set Route Mode to walking
directionsManager.setRequestOptions({ routeMode: Microsoft.Maps.Directions.RouteMode.walking });
var seattleWaypoint = new Microsoft.Maps.Directions.Waypoint({ address: 'Seattle, WA' });
directionsManager.addWaypoint(seattleWaypoint);
var redmondWaypoint = new Microsoft.Maps.Directions.Waypoint({ address: 'Redmond, WA', location: new Microsoft.Maps.Location(47.678561, -122.130993) });
directionsManager.addWaypoint(redmondWaypoint);
// Set the element in which the itinerary will be rendered
directionsManager.setRenderOptions({ itineraryContainer: document.getElementById('directionsItinerary') });
alert('Calculating directions...');
directionsManager.calculateDirections();
}
function createDirections() {
if (!directionsManager) {
Microsoft.Maps.loadModule('Microsoft.Maps.Directions', { callback: createWalkingRoute });
}
else {
createWalkingRoute();
}
}
getMap();
</script>
}
When you go first go on the Details page the map doesn't load. However if the page is then refreshed, then the map loads after. So to me this is some sort of loading problem. But after trying for few hours Im absolutely stuck.
Can anyone help? thanks
put the getMap() call into some place where it will be called after the page is loaded, for example the body onload event. If you are using jquery, $(document).ready().

Plupload with C# - Events?

I am newish to events, and new to flash. I have managed to get files uploaded to my folder using Plupload. I am using a generic handler (New to that too!)
Here's my code:
<style type="text/css">
#import url(/plupload/js/jquery.plupload.queue/css/jquery.plupload.queue.css);
</style>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<script type="text/javascript" src="http://bp.yahooapis.com/2.4.21/browserplus-min.js"></script>
<script type="text/javascript" src="/plupload/js/plupload.full.js"></script>
<script type="text/javascript" src="/plupload/js/jquery.plupload.queue/jquery.plupload.queue.js"></script>
<script type="text/javascript">
$(function () {
$("#uploader").pluploadQueue({
// General settings
runtimes: 'gears,flash,silverlight,browserplus,html5',
url: '/uploader.ashx',
max_file_size: '10mb',
chunk_size: '1mb',
unique_names: true,
preinit: attachCallbacks,
// Resize images on clientside if we can
//resize: { width: 320, height: 240, quality: 90 },
// Specify what files to browse for
filters: [
{ title: "Image files", extensions: "jpg,gif,png" },
{ title: "Zip files", extensions: "zip" }
],
// Flash settings
flash_swf_url: '/plupload/js/plupload.flash.swf',
// Silverlight settings
silverlight_xap_url: '/plupload/js/plupload.silverlight.xap'
});
// Client side form validation
$('form').submit(function (e) {
var uploader = $('#uploader').pluploadQueue();
// Validate number of uploaded files
if (uploader.total.uploaded == 0) {
// Files in queue upload them first
if (uploader.files.length > 0) {
// When all files are uploaded submit form
uploader.bind('UploadProgress', function () {
if (uploader.total.uploaded == uploader.files.length)
$('form').submit();
});
uploader.start();
} else
alert('You must at least upload one file.');
e.preventDefault();
}
function attachCallbacks(Uploader) {
Uploader.bind('FileUploaded', function(Up, File, Response) {
if ((Uploader.total.uploaded + 1) == Uploader.files.length) {
window.location = '/display.aspx';
}
});
}
});
And then in my code, my handler:
public class uploader : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
int chunk = context.Request["chunk"] != null ? int.Parse(context.Request["chunk"]) : 0;
string fileName = context.Request["name"] ?? string.Empty;
HttpPostedFile fileUpload = context.Request.Files[0];
var uploadPath = context.Server.MapPath(GlobalVariables.UploadPath);
using (
var fs = new FileStream(Path.Combine(uploadPath, fileName),
chunk == 0 ? FileMode.Create : FileMode.Append))
{
var buffer = new byte[fileUpload.InputStream.Length];
fileUpload.InputStream.Read(buffer, 0, buffer.Length);
fs.Write(buffer, 0, buffer.Length);
}
context.Response.ContentType = "text/plain";
context.Response.Write("Success");
}
public bool IsReusable
{
get { return false; }
}
}
This is working 100%
Problem is, when it complete the upload, nothing happens. It displayed the fact that the files were uploaded.
I need to somehow tell a new method to fire. That is, I need to process the uploaded files. Move them to the right folder ... name them better ... add them to a database, and maybe redirect to the display screen.
So, I need the flash control to tell my code to do something (An event) and also, tell my code which files it can now process (The list of files uploaded).
Is this possible?
Edit: I added the attachCallbacks method, and it's attached. It now redirects to a page, but I need to it somehow send the list of files uploaded to a method (generic handler maybe?) and process the files. How do I redirect to a method?
........
uploader.bind('UploadProgress', function () {
if (uploader.total.uploaded == uploader.files.length)
$('form').submit();
});
uploader.bind('UploadComplete', function (up, files) {
//files are uploaded, call script for each file...etc
});
uploader.start();
..........

ASP.Net MVC Jquery UI Autocomplete - list not showing up when I debug

I have implemented an autocomplete in my app for zip codes. I am debugging in Firebug and I see in my console that the action is performing and I get a list of zip codes in the list of results, but the actual list is not displaying when I debug.
Here's the action in my Customers controller:
//the autocomplete request sends a parameter 'term' that contains the filter
public ActionResult FindZipCode(string term)
{
string[] zipCodes = customerRepository.FindFilteredZipCodes(term);
//return raw text, one result on each line
return Content(string.Join("\n", zipCodes));
}
Here's the markup (abbreviated)
<% using (Html.BeginForm("Create", "Customers")) {%>
<input type="text" value="" name="ZipCodeID" id="ZipCodeID" />
<% } %>
and here's the order I load my scripts:
<script type="text/javascript" src="/Scripts/jquery-1.4.2.js"></script>
<script type="text/javascript" src="/Scripts/jquery.ui.core.js"></script>
<script type="text/javascript" src="/Scripts/jquery.ui.widget.js"></script>
<script type="text/javascript" src="/Scripts/jquery.ui.position.js"></script>
<script type="text/javascript" src="/Scripts/jquery.ui.autocomplete.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$("#ZipCodeID").autocomplete({ source: '<%= Url.Action("FindZipCode", "Customers") %>'});
});
</script>
Anything obvious that I'm missing? Like I say the script is grabbing the list of zip codes, they just won't display on my page when I test.
EDIT: I added an image that shows what I see in firebug - it appears that I get my zip codes back, but just won't display the dropdown.
I also updated my text box so that it's inside of the ui-widget div like so:
<div class="ui-widget">
<input type="text" name="ZipCodeID" id="ZipCodeID" />
</div>
and this is the script that I'm using:
<script type="text/javascript">
$(document).ready(function() {
$("#ZipCodeID").autocomplete('<%= Url.Action("FindZipCode", "Customers") %>');
});
</script>
I was able to get the autocomplete suggestions working using the following code:
Controller:
public JsonResult FindZipCode(string term)
{
VetClinicDataContext db = new VetClinicDataContext();
var zipCodes = from c in db.ZipCodes
where c.ZipCodeNum.ToString().StartsWith(term)
select new { value = c.ZipCodeID, label = c.ZipCodeNum};
return this.Json(zipCodes, JsonRequestBehavior.AllowGet);
}
Markup:
<script type="text/javascript">
$(document).ready(function() {
$("#ZipCodeID").autocomplete({
source: '<%= Url.Action("FindZipCode", "Customers") %>',
});
});
</script>
<div class="ui-widget"><input type="text" name="ZipCodeID" id="ZipCodeID" /></div>
I had huge problems with autocomplete few months ago when first setting it up. For instance, the simple default wireup like you do it never worked for me. I had to specify everything and also attach the result function to it.
This works 100% but it might not be suitable for you. But I hope it helps. Put both in document.ready() function.
$("#products").autocomplete('<%:Url.Action("GetProducts", "Product") %>', {
dataType: 'json',
parse: function (data) {
var rows = new Array(data.length), j;
for (j = 0; j < data.length; j++) {
rows[j] = { data: data[j], value: data[j].Title, result: data[j].Title };
}
return rows;
},
formatItem: function (row, y, n) {
return row.PrettyId + ' - ' + row.Title + ' (' + row.Price + ' €)';
},
width: 820,
minChars: 0,
max: 0,
delay: 50,
cacheLength: 10,
selectFirst: true,
selectOnly: true,
mustMatch: true,
resultsClass: "autocompleteResults"
});
$("#products").result(function (event, data, formatted) {
if (data) {
var item = $("#item_" + data.PrettyId),
edititem = $("#edititem_" + data.PrettyId),
currentQuantity;
// etc...
}
});
Try returning JSON from your controller action:
public ActionResult FindZipCode(string term)
{
string[] zipCodes = customerRepository.FindFilteredZipCodes(term);
return Json(new { suggestions = zipCodes }, JsonRequestBehavior.AllowGet);
}
Also don't forget to include the default CSS or you might not see the suggestions div appear.

Categories

Resources