I want to size of file in file upload control.
I am getting error in Internet Explorer. But This is code working in other browser.
Following code
var fuDocument = document.getElementById('<%= fupAttachment.ClientID %>');
var file = fuDocument.files[0];
if (file != null) {
var fileSize = file.size;
}
error 'files.0' is null or not an object
The only thing that I can think of is to use those good ol' ActiveX objects:
var axFile = new ActiveXObject("Scripting.FileSystemObject");
var fileObj = axFile.getFile(document.getElementById('<%= fupAttachment.ClientID %>').value);
var fileSize = {bytes: fileObj.size,
kBytes: Math.round(fileObj.size/1024),
mBytes: Math.round((fileObj.size/1024)/1024)};
That should offer support for older versions of IE, the full version could look something like:
var axFile, fileSize,
fuDocument = document.getElementById('<%= fupAttachment.ClientID %>');
if (fuDocument.files)
{
fileSize = fuDocument.files[0].size || 0;//default value = 0
}
else
{
axFile = new ActiveXObject("Scripting.FileSystemObject");
fileSize = (axFile.getFile(fuDocument.value) || {size:0}).size;//default to object literal, with size: 0 property --> avoids errors, and defaults to size value of zero
}
return fileSize;//console.log, alert... whatever you want
Related
I am working on a copy and paste feature for my website, so here is my problem. When i copy an image directly from a webpage it works as it should (the first if statement on the code), but if i am trying to copy a image from my own computer a i get a local path (like the one in the else statement)
$scope.pasteImage = function(eventPaste)
{
$scope.uploading = true;
var promises = [];
var items = (eventPaste.clipboardData || eventPaste.originalEvent.clipboardData).items;
for (var i = 0; i < items.length; i++)
{
var blob = null;
if (eventPaste.originalEvent.clipboardData.items[i].type.indexOf("image") == 0 || eventPaste.originalEvent.clipboardData.items[i] == 0)
{
blob = eventPaste.originalEvent.clipboardData.items[i].getAsFile();
}
else
{
var file = new File("file:///home/oem/testabc/vembly/source/server/images/pregnant.png")
console.log(file)
}
}
console.log(eventPaste)
console.log(blob)
var files = [blob];
uploadService.uploadMultiple(files)
}
so, my question is if its possible to transform that file (else statment) into a blob so i can use it in the uploadMultiple(files) funtction that i have.
No.
It would be a huge security problem if any website could use JavaScript to read data from any file path on your system it happened to guess existed.
When a video on my local storage—let's say it's currently located at file:///home/user/video.m4v—is opened by dragging it into a new tab in Chrome, how can I calculate the SHA-1 checksum for the file using JavaScript?
Purpose:
I am planning to write a Chrome extension which will store the calculated checksum of videos (files with extensions matching a pattern) as localStorage objects in order to save the playback position of video upon tab close and then restore it when the file is loaded again, even if the location or filename of the video is changed.
You need a crypto library for this. A well known one is Google CryptoJS.
I found this as an specific example for your task: https://gist.github.com/npcode/11282867
After including the crypto-js source:
function sha1sum() {
var oFile = document.getElementById('uploadFile').files[0];
var sha1 = CryptoJS.algo.SHA1.create();
var read = 0;
var unit = 1024 * 1024;
var blob;
var reader = new FileReader();
reader.readAsArrayBuffer(oFile.slice(read, read + unit));
reader.onload = function(e) {
var bytes = CryptoJS.lib.WordArray.create(e.target.result);
sha1.update(bytes);
read += unit;
if (read < oFile.size) {
blob = oFile.slice(read, read + unit);
reader.readAsArrayBuffer(blob);
} else {
var hash = sha1.finalize();
console.log(hash.toString(CryptoJS.enc.Hex)); // print the result
}
}
}
I wouldn't recommend to calculate a hash over the whole video file as it can be pretty resource consuming depending on the file size. Maybe you can use just the meta information or reconsider about the filename and filepath again?
Web APIs have progressed considerably since I asked this question. Calculating a hex digest is now possible using the built-in SubtleCrypto.digest().
TS Playground link
function u8ToHex (u8: number): string {
return u8.toString(16).padStart(2, '0');
}
/** Ref: https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest#supported_algorithms */
const supportedAlgorithms = [
'SHA-1',
'SHA-256',
'SHA-384',
'SHA-512',
] as const;
type SupportedAlgorithm = typeof supportedAlgorithms[number];
type Message = string | Blob | BufferSource;
async function hexDigest (
algorithm: SupportedAlgorithm,
message: Message,
): Promise<string> {
let buf: BufferSource;
if (typeof message === 'string') buf = new TextEncoder().encode(message);
else if (message instanceof Blob) buf = await message.arrayBuffer();
else buf = message;
const hash = await crypto.subtle.digest(algorithm, buf);
return [...new Uint8Array(hash)].map(u8ToHex).join('');
}
We recently implemented the ability of our members to upload an image. It has worked fine for several months. Recently it has stopped working in Chrome, but continues to work in Firefox, Safari, and Internet Explorer.
The error message that Chrome is generating is as follows:
Uncaught TypeError: Failed to set the 'files' property on 'HTMLInputElement': The provided value is not of type 'FileList'.
The code section that is having the problem is as follows:
$(window).load(function()
{
var aFiletypesAllowed = ["png","gif","jpeg","jpg"];
var FileTypesPrintable = 'png, gif, jpeg, jpg"';
var form = document.getElementById('image-submit');
var options =
{
thumbBox: '.thumbBox',
imgSrc: ''
}
var cropper = $('.imageBox').cropbox(options);
$('#file').on('change', function()
{
var reader = new FileReader();
reader.onload = function(e)
{
options.imgSrc = e.target.result;
cropper = $('.imageBox').cropbox(options);
}
reader.readAsDataURL(this.files[0]);
this.files = [];
fileSize = this.files[0].size;
fileName = this.value;
})
$('#btnCrop').on('click', function()
{
//file validation
var filetype = fileName.split('.').pop().toLowerCase();
fileWidth = cropper.getWidth();
fileHeight = cropper.getHeight();
//check file type
if (aFiletypesAllowed.indexOf(filetype) < 0)
{
var filenameUsed = fileName.split('\\').pop();
jConfirm('Invalid Filetype', filenameUsed + ' is not an allowed file type. Allowed filetypes are ' + FileTypesPrintable, '', '', '', '', '', '', '', '', 180);
document.getElementById('file').value = '';
}
//check image dimensions -- at least one dimension must be over the limit to ensure a crop occurs, and the image is modified in some way
else if (fileWidth < 200 && fileHeight < 200)
{
jConfirm('Image too Small', 'Minimum allowed image size is 200 x 200. Your image is ' + fileWidth + ' x ' + fileHeight + '. Please choose a larger image.', '', '', '', '', '', '', '', '', 180);
document.getElementById('file').value = '';
}
//validation passed, perform crop
else
{
var img = cropper.getDataURL();
$('.cropped').html('<img id="cropped-img" src="'+img+'">'); //image to display
$('#cropped-to-send').val(img); //dataURL to upload
}
})
The error message appears to be generated by the line of code "this.files = [];". After that error occurs, another error is thrown by line "var filetype = fileName.split('.').pop().toLowerCase();". The error on that line is "fileName is not defined".
As stated above, this function ran fine for several months in Chrome, and continues to work fine in Firefox, Safari and Internet Explorer.
I don't really understand how this function works, because it was implemented by another programmer based on a library. However, while inspecting the code, the one line "this.files = [];" seems to be problematic. That initializes an empty array; then the next two lines attempt to access elements of that array for later use. Of course, they will be empty.
So on a hunch, I re-arranged the order of some of the lines. The lines from the above code are as follows:
reader.readAsDataURL(this.files[0]);
this.files = [];
fileSize = this.files[0].size;
fileName = this.value;
I re-arranged them as follows:
reader.readAsDataURL(this.files[0]);
fileSize = this.files[0].size;
fileName = this.value;
this.files = [];
To me the function of these lines is as follows:
perform the data read;
assign some values
set this.files to an empty array
After doing this, the function now appears to work properly in Chrome.
My question now is more like: why was it working at all before in any browser? It seems that clearing the array, then trying to use the array is doomed.
And the second mystery is why did it work for several months? I have verified that this particular code has not changed in that period.
I had similar problem. Removing the line this.files = []; seams to fix the error, and since reader.readAsDataURL(this.files[0]); has already been called I don't think it will cause any much harm to the file upload. I think the error occurs because it expects a value of type FileList but does not match []
I'm trying to save the activeDocument as a .psd but its returning this error
ERROR: General Photoshop error occurred. This functionality may not be available in this version of Photoshop.
my script:
#target photoshop
var fileRef = new File(app.path.toString() + "/Samples/template.psd");
var docRef = open(fileRef);
//target text layer
var layerRef = app.activeDocument.layers.getByName("Text");
//user input
var newText = prompt("Editing " + layerRef.name, "enter new text: ");
//change contents
layerRef.textItem.contents = newText;
//save
var savePath = "/Samples/" + newText + ".psd";
var saveFile = new File(savePath);
var saveOptions = new PhotoshopSaveOptions();
saveOptions.alphaChannels = false;
saveOptions.annotations = false;
saveOptions.embedColorProfile = true;
saveOptions.layers = true;
saveOptions.spotColors = false;
app.activeDocument.saveAs(saveFile, saveOptions, true, Extension.LOWERCASE);
app.activeDocument.close();
what I want to do is basically, duplicate a template file over and over, only replacing the contents of a text layer then saving it under the string I replace in the text layer.
any tips or help is greatly appreciated.
Resolved
I fixed my problem, by a work around. I moved both the script and the template file into the Photoshop directory and added app.path.toString() to the saveFile output variable. So it seems that the path needed to be converted to a string before saving.
As of yet I am unsure how to work outside the Photoshop directory but for me this works so I'm happy. It's a fairly crude but I'm open to suggestion. So if anyone is having a similar issue they can use this for reference.
#target photoshop
var loop = true;
var filePath = "/Samples/template.psd";
while(loop) {
openTemplate(filePath);
var layerRef = app.activeDocument.layers.getByName("Text"); //target text layer
var newText = prompt("Editing " + layerRef.name, "enter new text: "); //user input
if(newText == "stop") { //stop loop by entering 'stop'
loop = false;
}
layerRef.textItem.contents = newText;
var savePath = app.path.toString() + "/Samples/" + newText + ".psd";
var saveFile = new File(savePath);
savePSD(saveFile);
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}
function openTemplate(filePath) { //open template.psd
var fileRef = new File(app.path.toString() + filePath);
var docRef = open(fileRef);
}
function savePSD(saveFile) { //saveas newText.psd
var saveOptions = new PhotoshopSaveOptions();
saveOptions.alphaChannels = false;
saveOptions.annotations = false;
saveOptions.embedColorProfile = true;
saveOptions.layers = true;
saveOptions.spotColors = false;
app.activeDocument.saveAs(saveFile, saveOptions, true, Extension.LOWERCASE);
}
I suspect the problem with your original attempt is that you are not specifying a full path. I always provide a full path - even if it is just to a temporary location like '/c/temp/myfile.psd'.
app.path returns a File object, not a string. In your case, you most likely want the platform-specific fullpath string:
var appPath = app.path.fsName; // "C:\Program Files\Adobe\Adobe Photoshop 2022"
Regardless if paths are correct, if you're attempting to save anything to a directory located inside the Photoshop installation directory, you will probably need to run Photoshop as administrator.
This seems like it should be easy. I've never used JScript before and I'm looking at the JScript api provided by microsoft but no luck. Here's what I have:
var fso, tf;
fso = new ActiveXObject("Scripting.FileSystemObject");
tf = fso.CreateTextFile("New Tracks.txt", true);
var objShell = new ActiveXObject("Shell.Application");
var lib;
lib = objShell.BrowseForFolder(0,"Select Library Folder",0);
items = lib.Items()
for (i=0;i<items.Count;i++)
{
fitem = items[i];
tf.WriteLine(fitem.Name);
}
WScript.Echo("Done");
tf.Close();
I get an error about fitem.Name that it's not an object or null or something. However, there are definitely files in that folder.
The items variable in your script holds a FolderItems collection rather than an array. To access the collection's items, you need to use the Items(index) notation. So, replacing
fitem = items[i];
with
fitem = items.Item(i);
will make the script work.
This works for me, I had to change the path to the file or I get access denied (win 7).
<script language="JScript">
var fso, tf;
fso = new ActiveXObject("Scripting.FileSystemObject");
tf = fso.CreateTextFile("c:\\New Tracks.txt", true);
var objShell = new ActiveXObject("Shell.Application");
var lib;
lib = objShell.BrowseForFolder(0,"Select Library Folder",0);
var en = new Enumerator(lib.Items());
for (;!en.atEnd(); en.moveNext()) {
tf.WriteLine(en.item());
}
WScript.Echo("Done");
tf.Close();
</script>
Apparently you can't access it like an array and have to call the Item() method.