How to access image file from HTML or Javascript for Windows Phone - javascript

I have a requirement in wp8, where the picture selected by the user needs to be shown in the browser. To browse and select the photo, I am using photo chooser task.
I am able to get the physical location of the selected image, but on passing the same to JavaScript from c# its not displaying the image.
On googling came across the following link How to access isolated storage file from HTML or Javascript for Windows Phone and PhoneGap Application But it did not solve my issue.
For reference, the location of the image I am using was:
C:\Data\Users\DefApps\AppData{FA586990-6E21-0130-BF9E-3C075409010C}\Local\sample_photo_00.jpg
This is my Javascript code:
function myPicture(data) {
document.getElementById("capturedImage").src = data.imageUri;
alert("data.imageUri " + document.getElementById("capturedImage").src );
var width = data.imageWidth;
var height = data.imageHeight;
alert("image width" + width );
alert("image height" + height );
}
And this is my C# code:
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
string[] picList = Directory.GetFiles(localFolder.Path, "*.jpg");
foreach (string DeleteFile in picList) {
File.Delete(DeleteFile);
}
StorageFile storageFile = await localFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
using (Stream outputStream = await storageFile.OpenStreamForWriteAsync())
{
await file.CopyToAsync(outputStream);
}
send (storageFile.Path);
Now send function should add MyHTML in picture.

You can call JavaScript function from C# by WebBrowser.InvokeScript and send image in args parameter. But args is string(s), so you will have to encode your image to string using some algorithm... Base64 for example:
string ImageToBase64String(Image image)
{
using (MemoryStream stream = new MemoryStream())
{
image.Save(stream, image.RawFormat);
return Convert.ToBase64String(stream.ToArray());
}
}
You will get some long string like this iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==
On other side - in the JavaScript function you calling you will get that Base64 string and use it like this as src attribute of img element:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" />
More info about data uri scheme.
UPDATE: The easer solution. I think you can send your image path, width and height:
ImageProperties properties = await storageFile.Properties.GetImagePropertiesAsync();
webBrowser.InvokeScript("myPicture", storageFile.Path, (string)properties.Width, (string)properties.Height);
function myPicture(src, width, height) {
document.getElementById("capturedImage").src = src;
alert("data.imageUri " + document.getElementById("capturedImage").src );
alert("image width" + width );
alert("image height" + height );
}

Related

Convert hexadecimal string to Blob and display PNG image with AngularJS

I got a web page (I/m using angularjs 1.4.8) and I'm trying to show an image which comes from my GET url request.
Here is the page code (I got a grid and I/m displaying previews if they are applicable):
<div ng-show="message.message == null && message.is_image != null">
<a href="#" ng-click="downloadFile(message.id_message)">
<img data-ng-src="data:image/{{message.image_resolution}};base64,{{message.image_preview}}"/>
</a>
</div>
So, I got cassandra DB with this blob field and my Json looks like:
created_date:"2017-03-31 22:05:42.284Z"
id_message:"e6e2a5cb-ec25-472f-a59b-3f16a3a8afa9"
id_user_link:"47ed65bf-5520-4901-88c8-01980ffbcd4d"
id_user_sent:"3495c2de-c93c-4323-8e48-1fcecbfde625"
image_length:174443
image_name:"5.png"
image_preview:"0x89504e470d0a1a0a0000000d49484452000007800000039a080600000079a04f28000038714944415478daecd9496e55570045d13bfff124d442c654016320c4d4219832046308a132087199c26ba4f1fed65ad29ec0e99e71ec97635392244992244992244992b4f90d23489224499
...
... some other 90 lines of symbols
...
00000108401d8006c0096244906600000000008c2006c0036004b922403300000000004610036001b802549920118000000008230001b800dc09224c9000c000000004118800dc00660499264000600000080200cc0066003b024493200030000004010066003b001589224198001000000200803b001d8002c49920cc000000000108401d8006c0096244906600000000008c2006c0036004b92a4ff95fe0ffc7d46dd1b63a2b10000000049454e44ae426082"
image_resolution:"png"
is_image:1
message:null
But I have no images in my web page (only icon of broken link to image):
I researched
Angularjs showing image blob
Display blob image in html with angularjs
AngularJS - Show byte array content as image
but this won't help.I tried some varieties of this code:
page:
<img data-ng-src="data:image/{{message.image_resolution}};base64,{{b64encoded(message.image_preview)}}"/>
js:
$scope.b64encoded = function(image_preview){
//btoa(String.fromCharCode.apply(null, response.data[0].ClassImage.data));
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|file|ftp|blob):|data:image_preview\//);
return btoa(String.fromCharCode.apply(null, image_preview));
}
RESOLVED
Finally, that was not the issue about AngularJS or blob - that was a Java issue:
byte[] previewSizeByte = baos.toByteArray(); and I stored this one as blob, so, now I got a text field and my Java code looks like (I decided to use BufferedImage for preview):
String base64String = imgToBase64String(preview, fileFormat);
and
private String imgToBase64String(BufferedImage preview, String fileFormat) {
final ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
ImageIO.write(preview, fileFormat, Base64.getEncoder().wrap(os));
return os.toString(StandardCharsets.ISO_8859_1.name());
} catch (final IOException ioe) {
throw new UncheckedIOException(ioe);
}
}
I really appreciate stackoverflow members for their comments and answers, they were extremely helpful
It appears that the CassandraDB is sending the image data as a hexadecimal string. It would be more efficient to send it as a base64 string and it would be easier to use.
Here is a function to convert a hexadecimal string to an image/png Blob and display the image:
angular.module("myApp",[]).controller("myVm", function($scope) {
var vm = $scope;
var testHex =
["0x89504e470d0a1a0a0000000d494844520000003c00000028040300000050",
"9584cc0000001b504c5445000000ffffff1f1f1f7f7f7f3f3f3f9f9f9f5f",
"5f5fdfdfdfbfbfbf2cb790f6000000097048597300000ec400000ec40195",
"2b0e1b000000b749444154388ded90cf0a83300cc63faaf5394a5defc56c",
"ee2a0c760e2a3b0b6e3ec7c0175f5aff1e77da657ea40dcd2ff90a010efd",
"9772a2f3f6ea4b830e121915b1a04e859999066a4b1801562dec544c3d36",
"cc723506ac9791809538f564af54055c33f8861d76d0cacfd30efc9450c3",
"b0e20189e28847aac5397458b7e2175d4cde4ed37252cff7d83ce367c849",
"b56014ecf638fa28bf62cd49b7c3e9a384f86764269cbde5bf665b969230",
"31adb25feffdd02ff50109f91bbd7897f34a0000000049454e44ae426082"]
.join('');
vm.hex = testHex;
vm.imgUrl = URL.createObjectURL(toPngBlob(testHex));
function toPngBlob(str){
var hexStr = str.slice(2);
var buf = new ArrayBuffer(hexStr.length/2);
var byteBuf = new Uint8Array(buf);
for (let i=0; i<hexStr.length; i+=2) {
byteBuf[i/2] = parseInt(hexStr.slice(i,i+2),16);
}
var blob = new Blob([byteBuf], {type: "image/png"});
return blob;
};
});
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="myApp" ng-controller="myVm">
<h1>Convert hex string to PNG Blob</h1>
{{hex}}<br>
{{imgUrl}}<br>
<img ng-src="{{imgUrl}}">
</body>

Html5 Audio tag doens't refresh content on page refresh

I'm developing a Radio website, I have created a C# back-end that writes an stream of bytes to the current HTTP response, which is then loaded on the HTML5 audio tag.
My problem is: I have for example 5 songs. The desired behavior is that every time the page loads, it should ask the controller for a random song to play. What actually happens is, the first time the page loads, the controller gets called and the song plays normally, but if the user reloads the page, or navigate to a new page and them back to the radio, the audio tag instead of calling the controller again, just plays what was downloaded in the audio buffer on the last call, and only when the buffer that was download finishes playing, the audio tag will call the controller, which creates undesired skips, like playing 15 seconds of a song and the starting a new song.
My audio HTML is created dynamically on a "render" method. I tried to make the id random, to try and force the buffer clean, but even with a new id, the tag will still play what was preloaded with the buffer, even if the preload attribute is set to "none". Besides that, I tried sending a random token as a parameter to the c# controller, to try and avoid any caching problems based on the URL, but it didn't work as well.
Heres my controller:
public void GetStream(StreamType? type, string token)
{
var files = this.GetFiles(type);
int rnd;
rnd = new Random((int)DateTime.Now.Ticks).Next(0, files.Count);
using (Stream mystream = files[rnd].OpenRead())
{
this.CurrentTrack = files[rnd].Name;
mystream.Position = 0;
using (BinaryReader reader = new BinaryReader(mystream))
{
byte[] bytes = new byte[mystream.Length];
System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
response.Clear();
response.ClearHeaders();
response.ClearContent();
response.BufferOutput = true;
response.ContentType = "audio/mp3";
response.AddHeader("Accept-Ranges", "bytes");
response.AddHeader("Cache-Control", "no-cache");
response.AddHeader("Content-Length", mystream.Length.ToString());
int bytesRead;
while ((bytesRead = reader.Read(bytes, 0, bytes.Length)) > 0)
{
response.OutputStream.Write(bytes, 0, bytesRead);
}
}
}
}
And here my JS:
audioApp.Initialize = function (type) {
audioApp.Render(type);
}
audioApp.Render = function (type) {
type = (type == undefined || type == null || type == "") ? 0 : type;
var token = audioApp.MakeId();
var html = "<div id='divSongName'>"
+ "</div>"
+ "<audio id='" + token + "' autoplay preload='none'>"
+ " <source src='/Streaming/GetStream/0" + type + "' type='audio/mp3' />"
+ " <em>Sorry, your browser doesn't support HTML5 audio.</em>"
+ "</audio>"
$("#divAudioRender").append(html);
}
the "Render" method will create the audio element that posts to my back-end.
I've searched a lot on the web for a way to force the audio buffer to be cleaned every time the page refreshes, but I couldn't find anything.
Any help is appreciated,
Thanks!
I finally figured out how to solve the problem! On my "Initialize" method that renders the audio element on the DOM, I added these below lines:
var audio = $("audio").get(0);
audio.src = "";
audio.src = "/Streaming/GetStream?type=" + type + "'&token=" + audioApp.MakeId();
audio.load();
audio.play();
When I changed the source to empty and force the player to load again, it clears the buffer, thus calling the controller on every refresh.
Add a nonce to the URL to make the browser think it's a different file each time.
So, instead of
src='/Streaming/GetStream/0" + type + (etc)
use
var d = new Date();
...
src='/Streaming/GetStream/0" + type + "?version=" + d.getMilliseconds() + (etc)

How to upload photo from library in webview in android app

I am using webview component on my android app. Users can load images from android photo library and show these images on a web page in the webview. How can I upload these image to my backend server from javascript?
Below is my java code to handle image chooser behavior:
setWebChromeClient(new WebChromeClient() {
#Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
Intent chooser = Intent.createChooser(intent, "Select Image");
activity.startActivityForResult(chooser, ResultCode.CHOOSE_PHOTO_REQUEST);
return false;
}
});
the above code will show image picker and when a user select an image, the onActivityResult will pass the selected image path to javascript as below:
if (resultCode == Activity.RESULT_OK) {
Uri imageUri = imageReturnedIntent.getData();
Log.d("IMAGE", "choose image uri " + imageUri);
String path = getRealPathFromURI(imageUri);
Log.d("IMAGE", "choose image real path " + path);
webView.loadUrl("javascript:choosePhotos('" + path + "')");
}
public String getRealPathFromURI(Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = {MediaStore.Images.Media.DATA};
cursor = mainActivity.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
in javascript, I can put the image path on a <img src=''/> tag to show the selected images. The path is something like this: '/storage/emulated/0/DCIM/Camera/IMG_20160808_200837.jpg'
It works fine here. But now I want to upload this image to my backend server. How can javascript handle this path: /storage/emulated/0/DCIM/Camera/IMG_20160808_200837.jpg.
You Can use filePathCallback to pass the selected file to webview.
Just create a global variable
ValueCallback filePathCallback;
and assign the parameter from onShowFileChooser() method to it.
then you can use this callback in onActivityResult() to pass the selected file to webview as :
Uri results[] = new Uri[]{imageUri};
filePathCallback.onReceiveValue(results);
then on html you will get file at

fetch image from library and change image every 30 seconds in sharepoint?

I'm using web part and i write the code below
but it fetch only one image >>> how can i fetch all image from the library and change image every 30 seconds using javascript or jquery??
public class MSDN : System.Web.UI.WebControls.WebParts.WebPart
{
Image myimage = new Image();
protected override void CreateChildControls()
{
myimage.Height = 140;
myimage.Width =999;
SPSite mysite = SPContext.Current.Site;
SPWeb myweb = SPContext.Current.Web;
SPList mylist = myweb.Lists["Pic Lib"];
SPQuery myquery = new SPQuery();
myquery.Query = "<OrderBy><FieldRef Name='FileLeafRef' />"+
"<FieldRef Name='Status' /></OrderBy>"+
"<Where><Eq><FieldRef Name='Status' />"+
"<Value Type='Choice'>Active</Value></Eq></Where>";
string serverpath = mysite.ServerRelativeUrl.ToString();
SPListItemCollection mylistitem = mylist.GetItems(myquery);
if (mylistitem.Count > 0)
{
myimage.ImageUrl = serverpath + mylistitem[mylistitem.Count - 1].Url.ToString();
}
else
{
this.Page.Response.Write("No image found");
}
base.CreateChildControls();
}
protected override void Render(HtmlTextWriter writer)
{
myimage.RenderControl(writer);
}
}
}
You can use the SharePoint Client Object Model MSDN link to query the list and get the image urls, store it in a javascript array
Then use any jquery plugin (like SlidesJS.. the first link on google) or write your own to flip the images every 30 seconds.

Image size validation

is it possible to validate file image size with jquery class orjavascript ?
Can i do that ? I made some research but did not reach anything
Thank you
If you want to check image file being uploaded on client side, check HTML5 File API. Here are some samples at:
http://www.html5rocks.com/en/tutorials/file/dndfiles/
You can get file size, find it's type and access binary content.
I was using File API to read EXIF headers from image without uploading image to server.
Here is a source code:
https://gist.github.com/980275/85da4a96a3bb23bae97c3eb7ca777acdea7ed791
Try this:
<input type="file" id="loadfile" />
<input type="button" value="find size" onclick="Size()" />
Script:
function Size() {
if ( $.browser.msie ) {
var a = document.getElementById('loadfile').value;
$('#myImage').attr('src',a);
var imgbytes = document.getElementById('myImage').fileSize;
var imgkbytes = Math.round(parseInt(imgbytes)/1024);
alert(imgkbytes+' KB');
}else {
var fileInput = $("#loadfile")[0];
var imgbytes = fileInput.files[0].fileSize; // Size returned in bytes.
var imgkbytes = Math.round(parseInt(imgbytes)/1024);
alert(imgkbytes+' KB');
}
}

Categories