I want to upload 2 scaled images and I do not want to upload the original image. To do this, I set sendOriginal to false. If I set hideScaled to true, no files show in the uploader. If set set hideScaled to false, both scaled images show up in the list. I realize that the documentation says not to use both options this way. Is there another way to achieve what I want? How do I make fineuploader show only 1 file on the file list no matter how many scaled images it has?
I ran into this exact same problem. I also wanted to rename the larger scale to match the original filename and to pass a custom parameter so the server script could sort the images into the db based on scale size.
I used this method as a hackish substitute for an onScaled event. If anyone is still interested.
// Must be onSubmitted, not onSubmit or the DOM element won't be rendered yet.
onSubmitted : function(id, name) {
// scaling.sizes.name = 'thumb'
if (name.toLowerCase().lastIndexOf(' (thumb).jpg') !== -1) {
// Hide the element displaying the thumbnail.
qq(this.getItemByFileId(id)).hide();
// Good place to include any custom parameters based on scale size.
this.setParams({gpsize : 'thumb'}, id);
}
// scaling.sizes.name = 'large'
else if (name.toLowerCase().lastIndexOf(' (large).jpg') !== -1) {
this.setParams({gpsize : 'large'}, id);
// If needed rename file in this event, not before, since filename
// is the hackish hook needed to connect scale size to file id.
var newName = name.slice(0, name.toLowerCase().lastIndexOf(' (large).jpg')) + '.jpg';
this.setName(id, newName);
}
return true;
}
It's not perfect, but it gets the job done without bushwhacking through the script files.
Related
Is there an equivalent of deleteProperty(XMPConst.NS_DC, "description”) or some way to clear out EXIF:ImageDescription, XMP-dc:Description and IPTC:Caption-Abstract with a Photoshop Script (ie, JavaScript or AppleScript)?
I am trying to remove the tags/descriptions below from TIF, PSD and PSB images:
[EXIF:IFD0] ImageDescription
[XMP:XMP-dc] Description
[IPTC] Caption-Abstract
I can do this with Exiftool with this code:
exiftool -m -overwrite_original_in_place -EXIF:ImageDescription= -XMP-dc:Description= -IPTC:Caption-Abstract= FILE
While that works great for me, I have lots of vendors that would need this in their workflows so it would be easier for them to use an action with the Photoshop Events Manager "On Document Open", or via an Automator script (Java or AppleScript) in their workflows than installing ExifTool. Looking for some help to do this...
I don’t have much coding experience, but I found the JavaScript code below on PS-Scripts as a starting point. This code doesn't require Photoshop which I like and could be done with Automator, but it only references the one tag. Also, I don’t need to write anything to the tags as this code does (I’d prefer just to delete or wipe the content and/or tags so they don’t show up).
Code: Select allvar f = File("/c/captures/a.jpg");
setDescription(f,"My new description");
function setDescription( file, descStr ){
if ( !ExternalObject.AdobeXMPScript ) ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript');
var xmpf = new XMPFile( File(file).fsName, XMPConst.UNKNOWN, XMPConst.OPEN_FOR_UPDATE );
var xmp = xmpf.getXMP();
xmp.deleteProperty(XMPConst.NS_DC, "description");
xmp.setLocalizedText( XMPConst.NS_DC, "description", null, "x-default", descStr );
if (xmpf.canPutXMP( xmp )) {
xmpf.putXMP( xmp );
}
xmpf.closeFile( XMPConst.CLOSE_UPDATE_SAFELY );
}
And below is an attempt at the JavaScript that would be used as a Photoshop Event on "Open Document"; but again I don't know how to amend to ensure all 3 tags reference above are cleared:
function removeDescription() {
whatApp = String(app.name);
if(whatApp.search("Photoshop") > 0)
if(!documents.length) {
alert("There are no open documents. Please open a file to run this script.")
return;
}
if (ExternalObject.AdobeXMPScript == undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
var xmp = new XMPMeta( activeDocument.xmpMetadata.rawData);
xmp.deleteProperty(XMPConst.NS_DC, "description");
app.activeDocument.xmpMetadata.rawData = xmp.serialize();
}
}
removeDescription();
Finally, below was an alternate that was tried that wipes the Description, ImageDescription and Caption-Abstract on TIFFs and PNGs on the first try, but takes running through twice to work on a PSD/PSB/JPG. I think it has to do with the interaction between Description, ImageDescription and Caption-Abstract, and the solution possibly resides with amp.setLocalizedText to nothing?
function removeMetadata() {
whatApp = String(app.name);
if(whatApp.search("Photoshop") > 0) {
if(!documents.length) {
alert("There are no open documents. Please open a file to run this script.")
return;
}
if (ExternalObject.AdobeXMPScript == undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
var xmp = new XMPMeta( activeDocument.xmpMetadata.rawData);
if (xmp.doesArrayItemExist(XMPConst.NS_DC, "description", 1))
{
xmp.deleteArrayItem(XMPConst.NS_DC, "description", 1);
}
app.activeDocument.xmpMetadata.rawData = xmp.serialize();
debugger
}
}
removeMetadata();
Here is an example Python script that uses the Pillow library to remove the metadata descriptions.
from PIL import Image
# Open the image file
image = Image.open('example.jpg')
# Remove the EXIF:ImageDescription metadata field
image.info.pop('EXIF:ImageDescription', None)
# Remove the XMP-dc:Description metadata field
image.info.pop('XMP-dc:Description', None)
# Remove the IPTC:Caption-Abstract metadata field
image.info.pop('IPTC:Caption-Abstract', None)
# Save the modified image file
image.save('example_modified.jpg')
Change "example.jpg" to your needs.
there may be other metadata fields that contain descriptions, depending on the specific image file format and how it was created. You may need to modify the script to remove additional fields if necessary.
So this is really frustrating... on the mymaths website: https://www.mymaths.co.uk/, there's an image of a primary school child on a computer with this image address: https://www.mymaths.co.uk/assets/images/big/primary-school-photo-2.jpg.
I've tried so many things, but I can't seem to replace it.
Say I wanted to replace it with a picture of a hamburger, with this address: https://images.ctfassets.net/sd2voc54sjgs/5L6livQvCw28S04IUSAcm6/6482ea1819e86be1b4f7e85bfbbfe9a6/Blog_Header_Hamburger_History_Option.png?fm=jpg&q=80&fl=progressive&w=1100.
So far I've tried lots of threads, but this image seems to be different from images on other websites, which is why my code isn't working on it:
var images3 = document.getElementsByTagName ("img");
var i3=0;
while(i3<images3.length)
{
if(images[i3].src == "https://www.mymaths.co.uk/assets/images/big/primary-school-photo-2.jpg")
{
images[i3].src = "https://images.ctfassets.net/sd2voc54sjgs/5L6livQvCw28S04IUSAcm6/6482ea1819e86be1b4f7e85bfbbfe9a6/Blog_Header_Hamburger_History_Option.png?fm=jpg&q=80&fl=progressive&w=1100";
}
i3=i3+1;
}
Can somebody help me please? Thank you.
Well, this was new for me too. Apparently, the <picture> tag is not just a wrapper - it's a smarter version of <img>.
It allows to chose different URLs for the image tag depending on screen size and type. For example, try to do this in developper tools:
I replaced srcset for the <source> that has (max-width: 767px), which means it is active when browser window is smaller than 767px. Now if you resize browser window to make it smaller, at some point the original image will be raplaced with burger image.
So what you want to do is to replace all <source>'s srcset. This worked for me:
// Limit the list of omages on those that are under `<picture>` tag
const images = document.querySelectorAll("picture img, picture source");
// RegExp to check if we want to replace the URL
const replaceChecker = /primary-school-photo-2\.jpg$/i;
// The replacement URL
const replaceWith = "https://images.ctfassets.net/sd2voc54sjgs/5L6livQvCw28S04IUSAcm6/6482ea1819e86be1b4f7e85bfbbfe9a6/Blog_Header_Hamburger_History_Option.png?fm=jpg&q=80&fl=progressive&w=1100";
for(const image of images) {
// Pick the name of the attribute we want to change based on whether it's <img> or <source>
const srcAttributeName = image.tagName.toLowerCase() == "img" ? "src" : "srcset";
const oldURL = image[srcAttributeName] + "";
if(replaceChecker.test(oldURL)) {
image[srcAttributeName] = replaceWith;
}
}
You could improve that by checking the media attribute and if it says minimum screen width, use URL for smaller image of the hamburger. That is set by the w GET param in the hamburger image's URL.
I've got an Array with 17 web links of images
var products:Array;
trace(products)
// Ouput :
"http://www.myWebsite.com/zootopia.jpg"
"http://www.myWebsite.com/james.jpg"
"http://www.myWebsite.com/tom.jpg"
..etc
If I do products[10].movieimage; the output will be the 9th link (something like : "http://www.myWebsite.com/lalaland.jpg")
I'm looking for downloading every images without a dialog box.
I manage to do so for 1 image with the specific link, like that :
function saveImage (event:Event):void {
var stream:URLStream = new URLStream();
var image1:File = File.documentsDirectory.resolvePath("test.jpg");
var fileStream:FileStream = new FileStream();
stream.load(new URLRequest("http://www.myWebsite.com/lalaland.jpg"));
stream.addEventListener(Event.COMPLETE, writeComplete);
function writeComplete(evt:Event):void {
var fileData:ByteArray = new ByteArray();
stream.readBytes(fileData,0,stream.bytesAvailable);
fileStream.openAsync(image1, FileMode.UPDATE);
fileStream.writeBytes(fileData,0,fileData.length);
fileStream.close();
trace("writeComplete");
trace(image1.url);
}
}
Question : Is there a way to download all the images with the web links of my products array ? (and if images already exist, replace them. I could use if (image1.exists){ if (image2.exists){ ..etc for each image. But maybe there is a simplier solution)
If you could show me how, with a bit of code, I could that.
Also, note that I'd like to load the images then in Uiloader, like that :
function loadImages():void {
uiloader1.source = image1.url;
uiloader2.source = image2.url;
etc...
}
Don't over think it. You have your array of images. You have your tested routine for saving one image. Now put it together:
Some function initializes things and kicks it off.
Either splice out (or pop out) an item on the array – OR use a index var to access an item in the array
Pass that to your download function.
When the download completes either pop another item off the array OR increment your index. But first you would test if array.length== 0 OR `index > array.length. If either is true (depending on which method you use), then you are done.
If you want to get fancy you can show a progress bar and update it each time your download completes.
I am using unveil.js to load a site more quickly.
I have a white div that blocks the content, which I want to disappear after the first images have loaded.
I though I could just count the images, but I realize that some of the latter ones could just load first (which normally happens because there is a threshold parameter which loads the ones that follow on the scroll).
Could someone help me with a smart way to do this?
Here's my code and the crappy solution:
$("img").unveil(2000, function() {
$(this).load(function(){
if(imageCount >= 4){
$(".white-cover").fadeOut("slow");
imageCount = 0;
}
Since unveil changes the src attribute, you can use jQuery to listen to an attribute change which indicate that an image has been replaced.
$(document).ready(function(){
$("#selected-date-range").change(function(){
alert( $("#selected-date-range").attr("value") );
});
});
In case I understand your problem correctly, I would use:
$(document).ready(function(){
// all images are loaded
}
Does this help you?
I am using data validation rules on a Google Spreadsheet.
In my scenario, I need users to entry only valid values. I use the 'Reject input' to force them to write only validated content.
However, the 'Reject input' option works for manually entried data only, but it does not work if the user pastes content into the cell from a different source (e.g. a MS Excel document). In that case, a warning is still shown but the invalid value is written.
In other words, I need the 'Reject input' option to work also with pasted content.
OR... another approach would be to programmatically check the validity of the value according the Datavalidation rule for that cell.
Any ideas?
Thank you in advance.
I had a little play with this.
I had inconsistent behavior from google.
On occasion when I ctrl-c and ctrl-p, the target cell lost its data validation!
To do this programmatically
Write myfunction(e)
Set it to run when the spreadsheet is edited, do this by Resources>Current Project's Triggers
Query e to see what has happened.
Use the following to gather parameters
var sheet = e.source.getActiveSheet();
var sheetname = sheet.getSheetName();
var a_range = sheet.getActiveRange();
var activecell = e.source.getActiveCell();
var col = activecell.getColumn();
var row = activecell.getRow();
You may wish to check a_range to make sure they have not copied and pasted multiple cells.
Find out if the edit happened in an area that you have data validated;
if (sheetname == "mySheet") {
// checking they have not just cleared the cell
if (col == # && activecell.getValue() != "") {
THIS IS WHERE YOU CHECK THE activecell.getValue() AGAINST YOUR DATA VALIDATION
AND USE
activecell.setValue("") ;
to clear the cell if you want to reject the value
}
}
The obvious problem with this is that it is essentially repeating programmatically what the data validation should already be doing.
So you have to keep two sets of validation rules synchronized. You could just delete the in sheet data validation but I find that useful for providing the user feedback. Also is the data validation you are using provides content it is practical to leave it in place.
It would be great if there was a way of detecting that ctrl-p had been used or one of the paste-special options and only run the script in those cases. I would really like to know the answer to that. Can't find anything to help you there.
Note also that if someone inserts a row, this will not trigger any data validation and the onEdit() trigger will not detect it. It only works when the sheet is edited and by this I think it means there is a content change.
onChange() should detect insertion, it is described as;
Specifies a trigger that will fire when the spreadsheet's content or
structure is changed.
I am posting another answer because this is a programmatic solution.
It has a lot of problems and is pretty slow but I am demonstrating the process not the efficiency of the code.
It is slow. It will be possible to make this run faster.
It assumes that a single cell is pasted.
It does not cater for inserting of rows or columns.
This is what I noticed
The onEdit(event) has certain properties that are accessible. I could not be sure I got a full listing and one would be appreciated. Look at the Spreadsheet Edit Events section here.
The property of interest is "e.value".
I noticed that if you typed into a cell e.value = "value types" but if you pasted or Paste->special then e.value = undefined. This is also true for if you delete a cell content, I am not sure of other cases.
This is a solution
Here is a spreadsheet and script that detects if the user has typed, pasted or deleted into a specific cell. It also detects a user select from Data validation.
Type, paste or delete into the gold cell C3 or select the dropdown green cell C4.
You will need to request access, if you can't wait just copy & paste the code, set a trigger and play with it.
Example
Code
Set the trigger onEdit() to call this or rename it to onEdit(event)
You can attach it to a blank sheet and it will write to cells(5,3) and (6,3).
function detectPaste(event) {
var sheet = event.source.getActiveSheet();
var input_type =" ";
if (event.value == undefined) { // paste has occured
var activecell = event.source.getActiveCell();
if (activecell.getValue() == "") { // either delete or paste of empty cell
sheet.getRange(5,3).setValue("What a good User you are!");
sheet.getRange(6,3).setValue(event.value);
input_type = "delete"
}
else {
activecell.setValue("");
sheet.getRange(5,3).setValue("You pasted so I removed it");
sheet.getRange(6,3).setValue(event.value);
input_type = "paste";
}
}
else { // valid input
sheet.getRange(5,3).setValue("What a good User you are!");
sheet.getRange(6,3).setValue(event.value);
input_type = "type or select";
}
SpreadsheetApp.getActiveSpreadsheet().toast('Input type = ' + input_type, 'User Input detected ', 3);
}