In an electron application, I am trying to display an image from the local disc in a window
that opens when a button in the main window is clicked.
The image's path is known at runtime only.
My first approach was to generate a new window that loads a template html-file
when the click event on that button is triggered and then set the
src-attribute of the img-element in this html template,
but I did not succeed in getting a handle on this img-element defined in
"imgView.html" (the following is from the renderer-process):
newWindowBtn.addEventListener('click', function(event){
let win = new BrowserWindow({
webPreferences: {
nodeIntegration: true
},
width: 500, height:500});
win.loadFile("imgView.html");
// how can the img-element defined in the template imgView.html
// be accessed here to set the src-attribute?
win.show();
win.on('close', function(){win=null})
})
I want to be able to have several windows open at the same time, with different images loaded.
My second approach was to dynamically generate the html to be loaded:
var html = [
"<body>",
"<p>Sample image: </p>",
"<img src=\"img.png\" style=\"width:90%\">",
"</body>"
].join("")
and replace the win.loadFile command in the newWindowBtn.addEventListener event-function
from above with
win.loadURL("data:text/html;charset=utf-8," + encodeURIComponent(html),
{baseURLForDataURL: __dirname + "/imgDir/"}
)
but apparently the image is not found (the rest of the page is loaded ok).
I played around with the format of baseURLForDataURL, but nothing worked.
Any ideas?
In some cases, I viewed that data:text/html;charset=utf-8," + encodeURIComponent(html) is not sufficient and you need to encode the html with base64: data:text/html;base64, + btoa(html).
Pay Attention
If this isn't a solution, this means that Electron doesn't allow to you to call the image because the page you'd like to load is considered an external page and you must encode the image with base64, too.
Related
I'm trying to make a chrome extension that will allow the user to choose the background color or font on the page and based on his choice a CSS file will be generated. Then the file would be injected into the page.
I've already tried to write some separate functions, every function for different elements and it's working great but 1) changes are not saved on the page, 2) functions are redundant, 3) I have no idea how to generate a CSS file from this.
This are chunks of code from content script I've already written (every function looks kinda similar):
colorPicker.onchange = function() {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.executeScript(
tabs[0].id,
{code: 'document.body.style.backgroundColor = "' + colorPicker.value + '";'}
)
})}
I also know that to inject CSS to page from chrome extension I can use:
chrome.tabs.insertCSS(tabId, {
file : "mystyle.css"
});
I really want to generate a CSS file instead of changing document properties one by one; but... how?
Any help would be greatly appreciated.
I'm creating a loading bar for my website and I want to update the loading progress (%) with each image load. For testing purposes, I used console.log() (instead of updating my loading bar).
I want to detect when each individual image loads. My images are all within <div id='images>
I have not found a solution that has worked after 5 hours of searching. I'm new to jQuery & Javascript, so I may have been using incorrect syntax (such as not targetting the image container correctly, but I'm not sure.
I have tried the imagesloaded jQuery plugin, but when using $('#images').imagesLoaded(), imagesloaded had said that all images had loaded, when they hadn't. (I'm testing using two 4k images so I can see the images slowly load).
The imagesloaded jQuery code I used for testing (loadProgress.js):
$('#images').imagesLoaded() //My images are within "<div id='images></div>"
.always( function( instance ) {
console.log('all images loaded');
})
.done( function( instance ) {
console.log('all images successfully loaded');
})
.fail( function() {
console.log('all images loaded, at least one is broken');
})
.progress( function( instance, image ) {
var result = image.isLoaded ? 'loaded' : 'broken';
console.log( 'image is ' + result + ' for ' + image.img.src );
});
// Code I used to keep track of when the page actually loaded
console.log('Page load started')
window.onload = function() {
console.log('Page load complete')
My HTML (Images were for testing purposes only and may be copyright) [just a snippit, not including doctype, body etc]:
<script src="https://unpkg.com/imagesloaded#4/imagesloaded.pkgd.min.js"></script>
<script scr="loadProgress.js"></script>
<div style="text-align:center" id="images">
<img src="https://wallpapers.gg/wp-content/uploads/2018/01/Old-Lion-4K.jpg" alt="Lion 4K" id='image' />
<img src="https://images7.alphacoders.com/383/383230.jpg" alt="Lion 4K" id="image" />
</div>
Console output [comment]:
Page load started
all images loaded
all images successfully loaded
[a good 5 second delay]
Page load complete
The output looks promising as the images are said to load after the page load has begun, but there is a 5 second delay between all images successfully loaded and Page load complete where I can see the images slowly render top-to-bottom and can also see the spinning loading icon in my browser tab (indicating that the images have not loaded yet, as there is no other html to load). I believe that the plugin is not correctly detecting the images container.
How can I (preferably automatically, not having to assing a unique ID to each image, and for them to collectively be found) detect when each individual image has loaded?
I'd like my console output to be (for example with two images):
Page load started
Image loaded
Image loaded
[no delay]
Page load complete
I am not looking to detect when all images have been loaded, and specifically want to repeat an action each time an image is loaded. In this case, the action would be console.log('Image loaded')
Using either Javascript or jQuery isn't a problem, and if you know a plugin which can achieve this more efficiently, I'd love to know.
I am not sure about the jQuery plugin you are using, but you could register an "onload" function to each image you want to load. No additional plugins/libraries needed, plain JavaScript should be fine.
Ideally, you would do it on backend side, not frontend, since images might be already loaded (think of browser cache) at the moment you assign the "onload" function.
If you want to target every image, just use the $('img') as your selector. If not, target their container element an you should be good to go.
late night here and at the end of my tether:
Incorporating Creative SDK to edit photos that were uploaded to the server via the previous page in the workflow -
I have tried every one of the parameters on the SDK documentation to find where is the fault in keeping the loaded image active for previewing edits, but in sequence,
Plugin Initialises (onLoad -> Ok)
Image loads (onReady -> Ok)
The Wait icon spins, then
The image disappears from the edit window
onError() does not pick this up.
Edits are functioning, onSave() fires and I can copy the image
(sending the adobe URL via AJaX) to a specified location (file output) on my
webspace, BUT, no live preview. Also the image does not update the original as is hard-coded in my script, and it gives an error as though unsaved on closing (isDirty).
My webspace is covered with an SSL certificate, but tried loading the image with relative and absoulte URLs, via http and https - nada.
I am calling version 3 as per the documentation, but people have said try version 4.3.1.29..?
I would like to presevere with this editor for live image editing, but only need it for cropping, adjusting brightness, contrast, rotation etc. and at the moment it is working, but 'blind' - anyone come across this? And how do I fix it...? :)
This is the source, pretty much as specified in the documentation, but with a working AJaX call while 'onSave()':
<script type="text/javascript" src="http://feather.aviary.com/imaging/v3/editor.js"></script>
<!-- Instantiate Feather -->
<script type='text/javascript'>
var featherEditor = new Aviary.Feather({
apiKey: 'my-key',
theme: 'dark', // Check out our new 'light' and 'dark' themes!
tools: 'all',
displayImageSize: 'true',
appendTo: '',
onSave: function(imageID, newURL) {
var img = document.getElementById("image1");
img.src = newURL;
var ph = document.getElementById("new_image_placeholder_div");
ph.innerHTML = '<img src="'+img.src+'" height="100">';
var xmlhttp_c;
if (window.XMLHttpRequest){xmlhttp_c=new XMLHttpRequest();} else {
xmlhttp_c=new ActiveXObject("Microsoft.XMLHTTP");}
alert("Passing the URL "+newURL+" to the PHP page...");
xmlhttp_c.open("GET", "feather_save_handler.php?newURL="+encodeURI(newURL), true);
xmlhttp_c.onreadystatechange=function() { if (xmlhttp_c.readyState==4 && xmlhttp_c.status==200) {
alert(xmlhttp_c.responseText);
alert("Saved!");
} else {
}
}
xmlhttp_c.send();
// end save AJaX call..
},
onError: function(errorObj) {
alert(errorObj.args);
}
});
function launchEditor(id, src) {
featherEditor.launch({
image: id,
url: src
});
return false;
}
</script>
The function is kicked off from a form button:
<form name="feather_editor" onSubmit="no_submit();">
<input type='image' src='http://images.aviary.com/images/edit-photo.png' value='Edit photo' onclick="return launchEditor('image1', 'http://mywebsitename.com/image_name.jpg');" >
</form>
It turns out that this is an issue in your CSS, and should be a fairly simple fix.
The issue
In daFooz_main.css, you have a canvas selector that includes:
z-index: -1;
That's causing the image in the Image Editor to effectively disappear from view since it is a canvas element.
The fix
The fix could be as simple as removing the line above from your CSS.
If you need that line for other areas of your site, try finding a way to be more specific with your selector, perhaps by using classes to target canvas elements that you do want to alter the z-index of.
I'm making a Chrome extension which in order to reduce bandwidth usage it stops all outcoming requests which are images.
I want to provide functionality where if the user clicks on the image (or technically a layer on top of that image) it would try to reload the image, this time not being blocked by the extension.
How can I tell the browser to retry loading the image? And if there isn't a straightforward way to do it, what would be a work around? Deleting the old image from the DOM and adding it again?
Any help is appreciated. :)
EDIT 1:
To answer #CBroe's question:
Using the chrome.webRequest.onBeforeRequest API in a background script.
To answer #jfriend00's question:
The usual placeholder "couldn't load image" icon, I guess also known as "broken file" icon:
See all those broken images?
That screenshot also illustrates the point of a layer on top of another image. Should those images not be broken, the loaded image would be there but that layer (the one in a dark grey which shows the image's dimensions) still remains there.
The desired href still exists there in the img tag:
If simply assigning the same src value to the img element is not enough¹, then create a new Image object in JavaScript, and assign the value to its src property.
¹ It might not be, if the browser just goes, “oh hey, that is the same value for the src attribute that the img already had, so I don’t have to do anything” – creating a new JS Image object however should make the browser request that resource again if he realizes he does not have it cached already.
What I would do instead is replace the URLs of the images with an image from your extension. A 1x1 pixel transparent GIF or PNG.
When you do this, add an attribute to all of the elements you replaced... something like data-yourextension-originalurl, with the URL of the original image. If the user then wants to load images, it's easy enough to go back and fix those image elements.
While I'm not too familiar with the Chrome API, a quick glance seems to suggest that there's no way to get the specific img element from each onBeforeRequest, which you'd need to know in order to figure out where to attach custom code.
This may be better accomplished with native JavaScript of some sort. For example, if Chrome lets you inject code on load, you could apply a function like the one below to all img elements after document load but before image load.
// Given an img element, replaces its src with a placeholder URL,
// and sets its click action to load its original src
function makePlaceholder(elem){
elem["data-oldtitle"] = elem.title;
elem["data-oldhref"] = elem.href;
elem["data-oldsrc"] = elem.src;
elem["data-oldonclick"] = elem.onClick;
elem.title = "Click to load the blocked image.";
elem.href = '';
elem.src = "http://example.com/placeholder.png";
elem.onClick = function(){
this.src = this["data-oldsrc"];
this.title = this["data-oldtitle"];
this.href = this["data-oldhref"];
this.onClick = this["data-oldonclick"];
};
}
The simple way to force reloading an image in JavaScript is:
var img = document.getElementById("myImage");
img.src = img.src.replace(/\?.+/,"") + "?" + new Date().getTime();
This adds a unique QueryString to the image which basically forces the browser to not use a cached version of the image.
I have a web page where lots of images called from server using image
scr attribute.
I have created a function like which is triggered by td click.
function GoToStep(stepNo) {
var imgSrc = $("#h1" + stepNo).val();
$(".img_vertical").css("background-image", "url(" + imgSrc + ")");
}
Now the problem is this. For slower connections the images come after some
moment.
Can I pre load images to avoid waiting time when user clicks
td?
I have seen some jquery function to pre load images.
Kindly give some idea how can I achieve it.
Pre-loading an image is equivalent to loading an image but never displaying it. So, you can easily do it like this:
<img src="image.png" alt="" style="display:none;"/>
Now this image will be loaded as soon as the html starts rendering. Whenever you need to use this image as a display or background, just set the address to image.png and it will automatically be fetched from browser's cache.
This can be done using some javascript functions. Quoting from another question.
function preload(arrayOfImages) {
$(arrayOfImages).each(function(){
$('<img/>')[0].src = this;
// Alternatively you could use:
// (new Image()).src = this;
});
}
// Usage:
preload([
'img/imageName.jpg',
'img/anotherOne.jpg',
'img/blahblahblah.jpg'
]);
Explanation of how javascript preloaders work (different question)
[...] The way it works is simply by creating a new Image object and setting
the src of it, the browser is going to go grab the image. We're not
adding this particular image to the browser, but when the time comes
to show the image in the page via whatever method we have setup, the
browser will already have it in its cache and will not go fetch it
again. [...]
So in your case, you should use something like
$(function() {
// Do stuff when DOM is ready
preload([
'img/bg1.jpg',
'img/bg2.jpg',
'img/bg3.jpg'
]);
});