Get images height and width in folder using JS before loading - javascript

I was wondering is there any script that before loading accesses all images in a specific folder, parses them to get their appropriate height and width so i would use them later on? This all needs to be done before loading anything into the webpage. Is there a way ?

The only conceivable way I can think of is to make a custom server, either a standard static server with python even, or even better, with nodeJS, then let the server automatically read either
a list of all of the file names in the folder, and send it to the client, then on the client side, stop the loading with JavaScript until each picture is loaded via ajax, and analyzed by drawing to a canvas, or even just setting it as the source for an img element, then waiting for the onload event of each, and checking the width and height [not gonna write up a full code example for this but let me know if you need more clarification]
Load everything on the server side, including a list of all of the images, and also find some kind of basic image processing library for the server side, for example something like pngjs for nodejs, to get the width and height for each image, after reading it with fs.readFileSync to get the raw binary data etc., then after getting the full array of image data with NodeJS, finally (if using createServer) call request.end.... etc., for your specific web page that is being hosted at
I'm not going to write up a full code example at this time but let me know if more clarification is needed

Related

Problem with Wordpress plugin sending base64 image data via Ajax - 400/404/500 errors

I'm Developing a WordPress plugin for customers to design custom T-Shirts, with the option of uploading their own images. The plugin takes several screenshots and emails them to a print department.
In Javascript I convert the screenshots to base64 data, which is then sent via Ajax to a PHP file, this creates a folder for the customer's design, creates the images from the data and stores the screenshots in there.
Most screenshots/base64 data send across just fine, for example just adding in text creates no problems. However if the user uploads an image and it's scaled up too much it causes various errors (sometimes 400 error, sometimes 404 and sometimes 500).
Running this through my local setup on Windows with Wamp, it's fine. I can upload images and scale them to 12x with no issues. However when I try this with the live site, I get the above problems if I scale any of the images past 4x, and with most images this happens if I even try to scale them up at all past 1x.
The resolution/file size of the image seems to have an effect, though not in an obvious way. I can send a huge plain red square, or normal image at 1x scale.
At first I thought this was a POST data limit issue, except the live site's POST limit is double that what I had set on my WAMP setup, which doesn't have this problem.
Also, and even stranger. I tested uploading the image but replacing the base64 data with simple characters (so the scaled up image exists in the page but it's base64 data isn't sent via POST), and I still have the same issue. So I don't think it's a simple POST limit issue.
Cannot for the life of me find a solution to this, any help would be hugely appreciated.
Figured a way round it, I'll give my solution in case anyone else has the same issue and comes across this post.
Basically I converted my base64 image data to a blob, and appended that to a newly created formData object. I found that also appending my nonce and action (amended to work with the admin-ajax way of using AJAX) to the formData helped deal with most issues on the javascript side. In the AJAX request I set processData and contentType to false.
As for the PHP side, I set a variable equal to the specific $_FILES array element I just sent. I used file_get_contents() on that variable (i.e the blob data), and wrapped that in file_put_contents() to actually write the image.
That's the quick version. If anyone wants a more detailed explanation let me know.

Force browser to reload all cache after site update

Is there a way to force the clients of a webpage to reload the cache (i.e. images, javascript, etc) after a server has been pushed an update to the code base? We get a lot of help desk calls asking why certain functionality no longer works. A simple hard refresh fixes the problems as it downloads the newly updated javascript file.
For specifics we are using Glassfish 3.x. and JSF 2.1.x. This would apply to more than just JSF of course.
To describe what behavior I hope is possible:
Website A has two images and two javascript files. A user visits the site and the 4 files get cached. As far as I'm concerned, no need to "re-download" said files unless user specifically forces a "hard" refresh or clears their cache. Once a site is pushed an update to one of the files, the server could have some sort of metadata in the header informing the client of said update. If the client chooses, the new files would be downloaded.
What I don't want to do is put meta-tag in the header of a page to force nothing from ever being cached...I just want something that tells the client an update has occurred and it should get the latest once something has been updated. I suppose this would just be some sort of versioning on the client side.
Thanks for your time!
The correct way to handle this is with changing the URL convention for your resources. For example, we have it as:
/resources/js/fileName.js
To get the browser to still cache the file, but do it the proper way with versioning, is by adding something to the URL. Adding a value to the querystring doesn't allow caching, so the place to put it is after /resources/.
A reference for querystring caching: http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.9
So for example, your URLs would look like:
/resources/1234/js/fileName.js
So what you could do is use the project's version number (or some value in a properties/config file that you manually change when you want cached files to be reloaded) since this number should change only when the project is modified. So your URL could look like:
/resources/cacheholder${project.version}/js/fileName.js
That should be easy enough.
The problem now is with mapping the URL, since that value in the middle is dynamic. The way we overcame that is with a URL rewriting module that allowed us to filter URLs before they got to our application. The rewrite watched for URLs that looked like:
/resources/cacheholder______/whatever
And removed the cacheholder_______/ part. After the rewrite, it looked like a normal request, and the server would respond with the correct file, without any other specific mapping/logic...the point is that the browser thought it was a new file (even though it really wasn't), so it requested it, and the server figures it out and serves the correct file (even though it's a "weird" URL).
Of course, another option is to add this dynamic string to the filename itself, and then use the rewrite tool to remove it. Either way, the same thing is done - targeting a string of text during rewrite, and removing it. This allows you to fool the browser, but not the server :)
UPDATE:
An alternative that I really like is to set the filename based on the contents, and cache that. For example, that could be done with a hash. Of course, this type of thing isn't something you'd manually do and save to your project (hopefully); it's something your application/framework should handle. For example, in Grails, there's a plugin that "hashes and caches" resources, so that the following occurs:
Every resource is checked
A new file (or mapping to this file) is created, with a name that is the hash of its contents
When adding <script>/<link> tags to your page, the hashed name is used
When the hash-named file is requested, it serves the original resource
The hash-named file is cached "forever"
What's cool about this setup is that you don't have to worry about caching correctly - just set the files to cache forever, and the hashing should take care of files/mappings being available based on content. It also provides the ability for rollbacks/undos to already be cached and loaded quickly.
i use a no-cache parameter for this situations...
a have a string constant value like (from config file)
$no_cache = "v11";
and in pages, i use assets like
<img src="a.jpg?nc=$no_cache">
and when i update my code, just change the $no_cache value, and it works like a charm.

Load image for HTML img element from JSON property while URL not directly accessible

OK, this one is rather complicated to explain, which explains the verbose title:
In my Objective C application I generate a JSON string to hold all of my properties for the objects I need to draw in the ARchitect browser of the wikitude SDK (as far as I know the Wikitude SDK only handles JSON) via:
NSString *javaScript = [self convertPoiModelToJson:self.poiData.pois];
NSString *javaScriptToCall = [NSString stringWithFormat:#"newData('%#')", javaScript];
One particular object I am interested in is stored as a string in that JSON string, it's the URL to an image. However, this image is behind a password protected area on our webserver and the app handles the authentication.
The problems start when I am in the ARchitect Browser, which is basically a .html file with calls to specific wikitude javascript functions to build the augmented reality world and show it in a UIWebView in the app. I want to show that image when a POI in the augmented view is clicked in the footer popup which is a basic html div container. So now I have a URL to an image resource on the webserver, which I cannot directly access with
document.getElementById("thumb").src = jsonObject.thumbUrl;
because of the authentication needed and the only way I was successful to load that image was via the var poiImage = new AR.ImageResource(jsonObject[i].iconURL, {onError: errorLoadingImage}); method but then I can only display it in the augmented view but not in the footer.
I tried it with providing a static string from some other image in the web or to local resources to the img element in the footer section in the view without problems like that: document.getElementById("thumb").src="marker.png"; and it works fine, also the image is correctly loaded in the augmented view.
I have read about encoding the image (which I can access and download in the objective c part of the app) in base64 and storing that string in an additional JSON property to load it into the src property of the html img element with a <img src="data:image/png;base64,BASE&$_ENCODED_DATA"></img> but this seems like a really dirty and overly impractical workaround/hack for what I try to accomplish. Also I don't know if it's a better idea to start reading about how to implement the authentication to access that image in the protected area of the webserver or rather begin implementing the ugly base64 encoding or continue searching for alternatives.
I'm not asking for a solution but rather for suggestions what possibilities I have left to access that image. Since I ran out of ideas, any help is appreciated.
Thank you!
Short summary:
image accessible and downloaded in objective c part
image is accessible with the AR.ImageResource method of the wikitude SDK (but not needed)
image cannot be accessed directly via the url from javascript because authentication is needed
(I hope my question is comprehensible, feel free to ask If something is unclear, especially since English is not my first language and it would be even complicated to explain that in German..)
Have you tried downloading the image in Objective-C / Cocoa, store it locally on your iOS device and pass the local path of the image via JSON into your Architect World?
You can then load the local image with your AR.ImageResouce and your div container.
Ok, let's think a bit about this, as it seems like a good mess.
If I'm understanding well your problem, all is about your javascript code needing to reach a url where an image is located, being unable to do so because that place requires some sort of validation to access.
In this scenario I'd look for moving images to a place out of the restricted site. Maybe trying to save them from the objective-C part into one public place that's reachable by javascript. This may be tricky as the I/O operation could slow your code execution... Of course you'll always have the option to move those images just outside of the restricted area but I supose that's not feasible as you could suposed that solution by yourself.
Other way... if your environment configuration allows it (I fear there isn't enough info about it on the question) is to try to execute your javascript part (I wonder if it's enclosed into a webpage executed from a webserver) with a user with permissions into the restricted area. This, of course, could be totally a no-no depending on what your javascript part does and why your restricted area is protected by validation.
If you don't want to move out the files, copy them temporarily gives performance problems and errors, and user impersonation through the javascript executing user is not an option I fear your unique alternative is to efectively try to pass a binary stream of data with the image through the JSON string... dirty...
Looks like wikitude maintains 2 browser contexts: the host browser that loaded your HTML and an embedded browser-like object (or iframe or proxy server) represented by the UIWebView instance.
Only one of those (not clear which from your discussion) has the user/pass for access to your image. You will need to call something to repeat the authentication step or transfer credentials to the other context.

Change an XML without changing it in server

I've got a llist of videos, with a click on a name it should display a video, the video-player i'm using read the video file name from a XML document in the same folder, I was thinking in, change the name of the file with javascript in the xml when a video name is clicked but I think this would change the original XML from the server and make it imposible for two people to view the page at the same time which actually sucks.
So is there any way to change only the XML on the user computer?
Or is there another way you can think to acomplish this job?
You can't change a (xml) file on the server easily. When you load it, the server will send you a stream of characters (call it string), which the browser will parse into a Document Object Model. This model is obvious locally, and when you modify it by using DOM manipulation methods like setAttribute, no one else will be affected.
To change a file on the server, you would need to explicitly request the server to do that.

Javascript read files in folder

I have the following problem which I'm trying to solve with javascript. I have a div with a background image specified in a css file, and I want my javascript to change that image periodically (let`s say every 5 secs).
I know how to do that, the problem is that I have a folder of images to choose from for the back image. I need to be able to read the filenames (from the image folder) into an array, change the background image of the div, delay for 5 seconds and change again.
in your javascript, use an array like
var images = [ "image1.jpg", "image2.jpg", "image3.jpg" ];
function changeImage() {
var image = document.getElementById("yourimage");
image.src=$images[changeImage.imageNumber];
changeImage.imageNumber = ++changeImage.imageNumber % images.length;
}
changeImage.imageNumber=0;
setInterval(changeImage,5000);
The values in the array should be generated by your php
You're still going to need php or asp to query the folder for files. Javascript will not be able to "remotely" inspect the file system.
You can do something like the following in jQuery:
$.ajax({
url: 'getFolderAsArrayOfNames.php',
dataType: 'json',
success: function(data) {
for(var i=0;i<data.length;i++) {
// do what you need to do
}
});
});
And in your getFolderAsArrayOfNames.php, something like this:
echo "function "
.$_GET['callback']
."() {return "
.json_encode(scandir('somepath/*.jpg'))
."}";
If you are using Apache as your
web server, and
if you can configure
it to provide a default directory
listing for your images folder (use
the appropriate options in
httpd.conf and/or .htaccess), and
if you don't care that the list of
images is available to everyone who
visits your web site,
then you don't need PHP or any other server-side processing.
You can use XMLHttpRequest (or the jQuery ajax function, which is a nice wrapper) to get the listing for the folder. The response will be HTML and it will look something like this:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<title>Index of /demo1/images</title>
</head>
<body>
<h1>Index of /demo1/images</h1>
<pre><img src="/icons/blank.gif" alt="Icon "> Name Last modified Size Description<hr><img src="/icons/back.gif" alt="[DIR]"> Parent Directory -
<img src="/icons/image2.gif" alt="[IMG]"> tree.gif 17-Mar-2009 12:58 6.2K
<img src="/icons/image2.gif" alt="[IMG]"> house.gif 17-Mar-2009 12:58 6.5K
<img src="/icons/image2.gif" alt="[IMG]"> car.gif 02-Mar-2009 15:37 8.4K
<img src="/icons/image2.gif" alt="[IMG]"> elephant.jpg 02-Mar-2009 15:37 3.4K
<hr></pre>
<address>Apache/2.0.63 (Unix) Server at zeppo Port 80</address>
</body></html>
Since this output is pretty predictable, you might try parsing out the filenames using a JavaScript regular expression, but it's probably just as easy and more robust to create a hidden DIV on your page, put the HTML response into that DIV, and then use DOM methods to find <a href>s that are after <img> tags with an alt="[IMG]" attribute. Once again, using jQuery Selectors or similar helper methods available in other toolkits will make this DOM parsing pretty easy.
Once you have the URL of the new image (parsed from the href), you can set the new CSS background for your div with the .style.backgroundImage property.
You cannot do any file IO using JavaScript mainly because of security reason, so anyway you have to create some back end service which will update you with an list of available files in your folder. You don't have to do it in a hard way, you can use AJAX to it smoothly and nicely
You can't read a folder's contents, neither on the server nor on the clientside.
What you can do is to read the folder's contents with the help of a serverside script, and load it to a JavaScript array while processing the page.
This would not be ideal but in the absence of server-side processing (which you really should be doing--either PHP or Rails or Perl or whatever your host supports), you could allow directory listing on your images folder. This has security implications.
Then loading e.g., http://mysite.com/rotatingImages should respond with a list of files. You could do this with AJAX, parse out the relevant hrefs, push them onto an array and render your rotating images in JS.
You must send the list of names along with the JavaScript and then iterate through it.
A noted above, you can not access server's system from a client's browser (which is where JavaScript runs).
You have 3 possible solutions:
Create the JavaScript file via some dynamic back-end (php or perl scripts are best for that).
The main JavaScript function could still be static but the initialization of the array used by it (either as a snippet on the main HTML page or a separate .js imported file) would be a php/perl generated URL.
A recent StackOverflow discussion of the topic is at link text
Make an XMLHttpRequest (AJAX) call from your JavaScript to a separate service (basically a URL backed by - again - php/perl backend script) returning XML/JSON/your_data_format_of_choice list of files.
This is probably a better solution if you expect/want/need to refresh a frequently-changing list of images, whereas a pre-built list of files in solution #1 is better suited when you don't care about list of files changing while the web page is loaded into the browser.
An un-orthodox solution - if browsers you care about support animated background images (gif/png), just compile your set of images, especially if they are small sized, into an animated gif/png and use that as background.

Categories

Resources