I'm trying to download a PNG image in Apps Script, convert it to JPEG, and generate a data URI for this new JPEG.
function test() {
var blob = UrlFetchApp.fetch('https://what-if.xkcd.com/imgs/a/156/setup.png').getBlob();
var jpeg = blob.getAs("image/jpeg");
var uri = 'data:image/jpeg;base64,' + Utilities.base64Encode(jpeg.getBytes());
Logger.log(uri);
}
When I run this, I get:
The image you are trying to use is invalid or corrupt.
Even something like:
function test() {
var bytes = UrlFetchApp.fetch('https://what-if.xkcd.com/imgs/a/156/setup.png').getBlob().getBytes();
var jpeg = Utilities.newBlob(bytes, MimeType.PNG).getAs(MimeType.JPEG);
DriveApp.createFile(jpeg);
}
doesn't work.
Your code is correct. This may be a bug, but it's specific to the file you are using, so may as well be a bug in the file (i.e., the file could indeed be corrupted somehow). Or maybe it uses some features of PNG format that Google doesn't handle. Replacing the URL by another one, e.g.,
var blob = UrlFetchApp.fetch('https://cdn.sstatic.net/Sites/mathematica/img/logo#2.png').getBlob();
both functions work as expected.
Related
I need to take a ticket id (only digits, but as a string), turn the string into a 1D barcode, then convert that to a image or bitmap or svg, then convert that into a base64 encoded string, where the base64 string can be returned as a response in a endpoint. It has be done in .NET6 and I'm doing it on a Mac (MacOS)
This is what I have so far (just put it in a console app for testing purposes):
using System.Drawing;
using BarcodeLib;
byte[] ImageToByteArray(Image image)
{
MemoryStream ms = new MemoryStream();
image.Save(ms,image.RawFormat);
return ms.ToArray();
}
var ticketId = "038000356216";
Barcode b = new Barcode();
Image img = b.Encode(TYPE.UPCA, ticketId, Color.Black, Color.White, 290, 120);
var barcodeAsString = Convert.ToBase64String(ImageToByteArray(img));
Console.WriteLine(barcodeAsString);
This does work because the Barcodelib uses Windows specific API's, which then causes a exception on the Mac. This code would properly work on a Windows machine. But since I'm on a Mac this is the the issue that I would like your help with.
How can I do this in a "platform neutral" way - something that will work on both MacOS and Windows?
I'm open for using any open source library/Nuget package that supports this - just as long as I don't have to pay for it, or there is going to be a waterwark on the image.
I have tried several libraries / Nuget packages - all with the same result as in the example.
I have several PDF documents that supposedly contain scanned images, but upon inspection in Acrobat Pro, each page contains a huge number of tiny "inline images". From what I understand these are not regular images inside XObjects, but rather images embedded directly inside content streams.
How could I go about extracting and merging these images?
The only code I could find online starts out like this:
var reader = new PdfReader(#"path\to\file.pdf");
PdfDocument document = new PdfDocument(reader);
for (var i = 1; i <= document.GetNumberOfPages(); i++)
{
PdfDictionary obj = (PdfDictionary)document.GetPdfObject(i);
// ... more code goes here
}
...but the rest of the code doesn't work because the PdfDictionary returned from GetPdfObject is not a stream, only a dictionary. I don't know how to access the images inside it.
Here is the problem I have:
My users can set their profile image either from Facebook (which is a jpeg or gif) or from local device (which could be png or jpg or others).
I get the image from Facebook by using:
// Get the name, email and picture
final graphResponse = await http.get(
'https://graph.facebook.com/v4.0/me?fields=name,email,picture.width(300).height(300)&access_token=$token');
// Decode JSON
final profile = jsonDecode(graphResponse.body);
final String stringData = profile['picture']['data'];
final bytes = Uint8List.fromList(stringData.codeUnits);
And getting image from local device by:
final imagePicker = ImagePicker();
// Call image picker
final pickedFile = await imagePicker.getImage(
source: ImageSource.gallery,
maxWidth: MAX_WIDTH_PROFILE_IMAGE,
);
final imageBytes = await pickedFile.readAsBytes();
Then all I got here are in bytes (Uint8List), how do I save it according to its original extension?
Then later on how do I read them again without checking its extension?
Such as with:
// Setting the filename
// Could be jpg or png or bmp or gif.
// How to determine the extension?
final filename = 'myProfileImage';
// Getting App's local directory
final Directory localRootDirectory =
await getApplicationDocumentsDirectory();
final String filePath = p.join(localRootDirectory.path, path, filename);
final file = File(filePath);
You see, when reading the file we need to specify the full filename. But how to determine the extension then ?
You can avoid dealing with extensions completely by simply not setting an extension in the filename. Extensions only exist to indicate what is likely contained within a file for an OS, but they are not necessary and aren't needed in your case especially since you know that you have some kind of image data in that file and you application is probably the only thing ever using that file.
However, if you really do want to use extensions in the filename, you can use the image package. This provides a Decoder abstract class with multiple implementers for a variety of image encoding methods. To determine which method was used for your file you could check with the isValidFile of each possible decoder type that you need and write an extension accordingly.
Example:
PngDecoder png = PngDecoder();
if(png.isValidFile(data //Uint8List inputted here)) {
print("This file is a PNG");
}
function extractTextFromPDF() {
// PDF File URL
// You can also pull PDFs from Google Drive
// this Fall2019_LLFullCatalog.pdf will not insert - internal error on insert is all the feedback that gets logged"
// doesn't matter if I retrieve it from the university website or if I first copy it to my google drive and then retrieve it from there
//var url = "https://uwf.edu/media/university-of-west-florida/offices/continuing-ed/leisure-learning/docs/Fall2019_LLFullCatalog.pdf";
//var url = "https://drive.google.com/drive/u/0/my-drive/Fall2019_LLFullCatalog.pdf";
// both of these pdfs will insert just fine. Size is not the issue because this one is much larger than the one I need to insert
var url = "https://eloquentjavascript.net/Eloquent_JavaScript_small.pdf";
//var url = "https://img.labnol.org/files/Most-Useful-Websites.pdf";
var blob = UrlFetchApp.fetch(url).getBlob();
var size = blob.getBytes().length;
var resource = {
title: blob.getName(),
mimeType: blob.getContentType()
};
// Enable the Advanced Drive API Service
var file = Drive.Files.insert(resource, blob, {ocr: true, ocrLanguage: "en"});
// Extract Text from PDF file
var doc = DocumentApp.openById(file.id);
var text = doc.getBody().getText();
return text;
}
See comments in code above that describe the problem.
The PDF that I need to insert with OCR is not working - regardless of whether I retrieve it from the original site or retrieve a copy that I put on google drive. However, two other PDF urls will insert just fine and one of them is considerably larger than the one that fails.
What else could be the issue, if not size limitation?
Thanks,
Steve
It could very well be a bug in the Chrome API. Not all PDF software is created equal, check if the PDF can be read in Adobe Acrobat as a simple test.
I want to convert an Embedded image to base 64 string. The image is in PCL solution so let me know how to convert an image into base64. As I tried lots of ways but I am not getting the file path properly. So please help me with this.
//file to base64 string
byte[] b = System.IO.File.ReadAllBytes(FileName);
String s = Convert.ToBase64String(b);
//base64 string to file
byte[] data = Convert.FromBase64String(s);
System.IO.File.WriteAllBytes(FileName2, data);
Since it is an embedded resource getting the path for the image is a problem to convert it into a stream, you can take the following steps to get the path of your embedded image:
string imagePath = "NameOfProject.Assets.applicationIcon.png";
Note: This is the sample path in your case you will give your path, Where the name of the project is the name of the project, Assets is the folder in which I have the image and application icon is the image. (I hope you understood what I am doing here)
After that get the Assembly details something like this:
Assembly assembly = typeof(NameOfClass).GetTypeInfo().Assembly;
Then inside a using statement convert your image into a stream, Something like this
string result;
using (Stream stream = assembly.GetManifestResourceStream(imagePath))
{
long length = stream.Length;
byte[] buffer = new byte[length];
stream.Read(buffer, 0, (int)length);
result = Convert.ToBase64String(data);
}
Revert in case of queries.