I'm making a simple slider to show off artwork for a friend of mine. I'm really only familiar with javascript/jquery, so I'm not 100% comfortable using something else right now.
Since my friend doesn't have any programming knowledge, I'm trying to keep this really simple for her to update (i.e., automating creating new images whenever she adds a new one to the folder). She will upload images to a folder and will have to number them (i.e., 1.jpg, 2.jpg). My javascript uses a for loop to loop through numbers (she will have to update the loop whenever she adds a new image) and insert them into the file name. HOWEVER this limits her to only uploading one type of file. Is there someway to change the extension only using javascript?
This is what I have so far:
function callImages(){
//create the image div
$('.artslider').append('<div class="image"></div>');
//create the files array
var files = [];
//start the loop, starting position will have to be updated as images are added
for (i=8;i>=0;i--){
//create the img src for a jpg img
var imgJPG = 'arts/'+i+'.jpg';
//find the natural width of the image after it loads to see if it actually exists
var imgWidth = $('imgJPG').load().naturalWidth;
//if the width is undefined, replace the jpg extension with gif
if (imgWidth===undefined){
var imgGIF = imgJPG.replace('jpg', 'gif');
files[i] = '<img src="'+imgGIF+'" class="artsliderimg"/>';
}
//otherwise keep the jpg extension
else {
files[i] = '<img src="'+imgJPG+'" class="artsliderimg"/>';
}
//then add the images to the img div
$('.image').append(files[i]);
}
};
The problem with this if/else is that it will only create a gif image. If you switch the order, it will only create a jpg image.
edit: here's what this code produces: https://googledrive.com/host/0B1lNgklCWTGwV1N5cWNlNUJqMzg/index.html
The problem is with this bit of code:
var imgJPG = 'arts/'+i+'.jpg';
var imgWidth = $('imgJPG').load().naturalWidth;
imgWidth will always be undefined.
Firstly you are passing in the string 'imgJPG' instead of the parameter imgJPG. Secondly I think you have misunderstood jQuery selectors, this is used for selecting HTML elements, inputting a file path into here will not achieve anything. Thirdly I think you have misunderstood the load function, this is used for loading data from the server into a HTML element.
I would suggest using a function like below to check if the image exists:
function urlExists(url) {
var http = jQuery.ajax({
type:"HEAD",
url: url,
async: false
});
return http.status == 200;
}
Then in your code:
if (!urlExists(imgJPG)){
var imgGIF = imgJPG.replace('jpg', 'gif');
files[i] = '<img src="'+imgGIF+'" class="artsliderimg"/>';
}
else {
files[i] = '<img src="'+imgJPG+'" class="artsliderimg"/>';
}
Related
I have been trying to upload an image and convert it into grayscale version then display both images on a webpage. I have test and verified the working of the javascript code locally and it works. However when I integrate it into my webpage only the orignal image is being uploaded. The greyscale image is not being generated or the function is not being processed.
function doUpload(){
var image = new SimpleImage(inputFile);
image.drawTo(CanvasOG);
var imageGS = grayScale(image);
imageGS.drawTo(CanvasGS);
//var NewImage = grayScale(image);
//NewImage.drawTo(CanvasGS)
}
Can you tell me what went wrong?
PS Im using the Duke university's learn to program course's SimpleImage library for the functions to read the images and pixel values
Im posting a link to the codepen page incase you want to see the entire code with the html page
https://codepen.io/girish-kumar-peddi/pen/PoPBxKb
The nature of SimpleImage.js drawTo() contains a setTimeout(). Thus the imageData is not set instantly, but after 100ms. So after the image is drawn to the canvas, wait sometime before manipulating the image data. Enclosed the drawTo() implementation below.
// Draws to the given canvas, setting its size to match SimpleImage's size
drawTo: function (toCanvas) {
if (this.imageData != null) {
__SimpleImageUtilities.flush(this.context, this.imageData);
toCanvas.width = this.getWidth();
toCanvas.height = this.getHeight();
toCanvas.getContext('2d').drawImage(this.canvas, 0, 0, toCanvas.width, toCanvas.height);
}
else {
var myself = this;
setTimeout(function() {
myself.drawTo(toCanvas);
}, 100);
}
},
I'm trying to make an Image sequence scrolling website, something like Apple Airpod Pro.
I'm facing an issue with images loading, each image will load once it displays only.
It appears that I have to preload all images on dom to cache it out so it'll look smooth when scrolling.
So I'm looking for a better way to cache my images
Here is my image array :
const MAX = 4875; //last image number
const PREFIX = "images/image-scroll/Test_"; //image location
const EXT = ".jpg"; //image format
var images = [];
for (let i = 0; i <= MAX; i += 1) {
images.push(
PREFIX + ("00000" + i).slice(-5) + EXT
);
}
Currently, I'm preloading images this way:
//Preload Images
jQuery('document').ready(function(){
jQuery.each(images, function() {
jQuery('<img />').attr('src', this).appendTo('body').hide();
});
});
This method works, but it makes the site heavy and it'll keep creating img elements every time you update the page.
Is it possible if I can just load all images to cache it without adding elements to the code?
One possible solution is to call GET requests to the image URLS directly instead of waiting for browser to call it from the DOM element. This way the DOM is not modified and the images may be cached in the browser.
The network and caching layers should work similarly to how it would if you had added it to DOM.
//Preload Images
jQuery('document').ready(function(){
jQuery.each(images, function() {
fetch(this); // uses the fetch API to do a get request. You may use the jQuery AJAX if required.
});
});
I'm pretty new to JavaScript and I was making a simple project. Basically I have an HTML document and I want to change the background image every time it is opened up to a random picture from a directory located at 'Background'.
function main()
{
// Creates a list of filenames from the 'Background/' dir and gets a
// random index in the list
var fs = require('fs');
var fileList = fs.readdirSync('/Background/');
var len = fileList.length;
var index = Math.floor(Math.random() * len);
var filePath = "Background/" + fileList[index];
document.body.style.backgroundImage = "url(filePath)";
document.body.style.backgroundSize = "cover"
}
$(document).ready(main);
For whatever reason it doesn't seem to work. I'm having trouble figuring out exactly how the URL class works, because I think it has something to do with that. I'm not getting any errors. I got the background image to change to specific image when I did this:
document.body.style.backgroundImage = "url('Background/green.jpg')";
But not when I try and retrieve the filenames randomly.
I'm sure it's just a misunderstanding of the language or something but I can't seem to figure it out. Thanks.
You can't use fs in this way in browser. You need to store images paths. You can store them in database or in array in your javascript file. Below example with storing filenames in array.
function main()
{
var images = ['image1.jpeg', 'image2.jpg', 'bg.png'] //storing only names
var index = Math.floor(Math.random() * images.length)
var filePath = "Background/" + images[index]; //creating full path
document.body.style.background = 'url("'+filePath+'")'
// if background-size is not changing, it's better to store it in .css file
}
$(document).ready(main);
I have a program where a camera is set up to constantly take pictures (about every 10 seconds or so) and the picture is sent to a folder on my server and then another program refreshes that folder constantly so that I always just have the most recent picture in that particular folder.
An HTML document exists that also constantly refreshes, and references that picture location to get and display the newest image.
What I'm trying to do is extract the EXIF data (that I've verified exists when I save the image from the active webpage and look at it's properties). I want to display the DateCreated (I believe this is DateTime) and the Latitude and Longitude (I believe is GPSLatitude and GPSLongitude).
I came across this library, exif-js, which seems like the go-to for most people trying to do this same thing in JavaScript. My code looks the same as the code at the bottom of the README.md file, except I changed out my img id="...." and variable names, (see below). It seems like it should work, but it's not producing any data. My empty span element just stays empty.
Is there an issue with the short time span that the page has before refreshing?
Thanks for any help!
Here's what my code currently looks like (just trying to get the DateTime info). I have also tried the GPSLatitude and GPSLongitude tags.
<!-- Library to extract EXIF data -->
<script src="vendors/exif-js/exif-js"></script>
<script type="text/javascript">
window.onload=getExif;
function getExif()
{
var img1 = document.getElementById("img1");
EXIF.getData(img1, function() {
var time = EXIF.getTag(this, "DateTime");
var img1Time = document.getElementById("img1Time");
img1Time.innerHTML = `${time}`;
});
var img2 = document.getElementById("img2");
EXIF.getData(img2, function() {
var allMetaData = EXIF.getALLTags(this);
var allMetaDataSpan = document.getElementById("Img2Time");
allMetaDataSpan.innerHTML = JSON.stringify(allMetaData, null, "\t");
});
}
</script>
go into ur exif.js file and then go to line 930 and then change it to
EXIF.getData = function(img, callback) {
if ((self.Image && img instanceof self.Image
|| self.HTMLImageElement && img instanceof self.HTMLImageElement)
&& !img.complete)
return false;
I know this may be already solved but I'd like to offer an alternative solution, for the people stumbling upon this question.
I'm a developer of a new library exifr you might want to try. It's maintained, actively developed library with focus on performance and works in both nodejs and browser.
async function getExif() {
let output = await exifr.parse(imgBuffer)
console.log('latitude', output.latitude) // converted by the library
console.log('longitude', output.longitude) // converted by the library
console.log('GPSLatitude', output.GPSLatitude) // raw value
console.log('GPSLongitude', output.GPSLongitude) // raw value
console.log('GPSDateStamp', output.GPSDateStamp)
console.log('DateTimeOriginal', output.DateTimeOriginal)
console.log('DateTimeDigitized', output.DateTimeDigitized)
console.log('ModifyDate', output.ModifyDate)
}
You can also try out the library's playground and experiment with images and their output, or check out the repository and docs.
I have a Google Chrome extension I am building for adding new bookmarks to my bookmarks app.
One of the features of my bookmark app is allowing to save a screenshot image of the web page and up to 3 additional images.
IN the Chrome extension, the 3 additional images show as a text input to insert an image URL.
Under each input I have scraped the web page HTML to find all images in the page and I show them in a slider with previous and next arrow buttons to rotate and view all the images on the page. If the user likes one of the images on the page, they can select it in this slider which then converts the image to Base64 encoded string and uploads to my remote bookmark app server.
My problem is that in the image selector where I show the images from the web page, it shows a broken image for any image that was in the page and was linked with a relative path instead of a full path with a domain name in it.
(last image shown in the 4 images in this animated GIF below shows the 4th is a broken image)
If I view the page source and see a relative linked image like this...
Then this image will show as a broken image in my image selector/slider in my extension as it will then link to the image like this where the relative linked image ends up getting the extension URL in front of it...
Below is my JavaScript function which scrapes the HTML and grabs the images found in the page.
I need to detect when the image URL is a relative linked image and then inject the page URL in front of the image URL to make it a absolute path linked image.
Any ideas how to achieve this?
Relative image urls currently end up linking to the image with this as the "domain"... chrome-extension://pcfibleldhbmpjaaebaplofnlodfldfj.
I need to instead inject the URL of the web page in front of all relative linked images.
In my JS function below where it saves the Image URL to an array,
var img.src looks like this on relative URL's...
So If I could simply replace chrome-extension://pcfibleldhbmpjaaebaplofnlodfldfj with the webpage URL that would fix my problem.
The chrome extension URL is different though so would need to match that pattern.
JavaScript function to get all images in an HTML string:
/**
* Scrape webpage and get all images found in HTML
* #param string $htmlSource - HTML string of the webpage HTML
* #return array - array of HTML strings with list items and images inside each list item
*/
scrapeWebpageForImages: function($htmlSource) {
// HTML source code of the webpage passed into jQuery so we can work on it as an object
var $html = $($htmlSource);
// All images
var images = $('img', $html),
scanned = 0,
filtered = [],
ogtmp = '',
srcs = {};
// Grab the open graph image
var ogimage = $('meta[property="og:image"]', $html);
if( ogimage.length > 0 ) {
ogtmp = $('<img>').prop({
'src': $(ogimage).text(),
'class': 'opengraph',
'width': 1000, // High priority
'height': 1000
});
images.push(ogtmp);
}
var i = 0,
l = images.length,
result = '',
img;
// Cycle through all images
for(; i < l; i++) {
scanned += 1;
img = images[i];
// Have we seen this image already?
if( !! srcs[$(img, $html).attr('src')] ) {
// Yep, skip it
continue;
} else {
//////////////////////////////////////
///
/// NEED TO DETECT A RELATIVE LINKED IMAGE AND REPLACE WITH ABSOLUTE LINKED IMAGE URL
/// USING THE WEBPAGE URL
///
//////////////////////////////////////
// Nope, remember it
srcs[$(img, $html).attr('src')] = true;
result = '<li><img src="'+img.src+'" title="'+img.alt+'"></li>';
filtered.push(result);
}
} // end for loop
return filtered;
},
var url = "chrome-extension://pcfibleldhbmpjaaebaplofnlodfldfj/assets/xyz";
var myRe = /chrome-extension:\/\/[\w]*/g;
var match = myRe.exec(url);
if(match.length > 0) {
// Pattern matched
var path = url.substring(match[0].length);
url = 'whatever your base url is' + path;
} else {
console.log('Did not find a url.');
}