Telegram's instant view: fails to load .webp and .ico images - xpath

I have a problem when trying to create my Telegram's Instant View template, with this error:
Resource fetch failed: https://gdude.de/blog/assets/images/Kaggle-Lyft/task.webp
Resource fetch failed: https://gdude.de/blog/assets/images/telegram.ico
The URLs are valid, I have checked.
These are the only two images that fail. Does IV support *.webp and *.ico images?

According to their manual, Instant View is only actually supporting gif, jpg and png.
with the attribute src and the optional attribute href to make the image clickable. Allowed formats: GIF, JPG, PNG (GIF would be converted into Video type by IV)

I had a similar problem and solved it in the following way.
Note: You need a hosting server to store a PHP script, a free one worked for me (000Webhost).
The diagram below represents the general idea
Instant View code
Note: I'm a beginner at Instant View and XPath, so for now I'm just writing code that works.
# Find unsupported images
$imgs: //img[ends-with(#src, ".webp")]
$imgs+: //img[ends-with(#src, ".ico")]
# Temporary element to create the URLs and make calls to the conversion service
#html_to_dom: "<a>"
$tmp_tag
# For each unsupported image
#map($imgs){
$img: $#
# Build de URL to request the image conversion service
#set_attr(href, "https://my-free-subdom.000webhostapp.com/imgconverter.php?url=", $img/#src): $tmp_tag/a
# Make the request
#load: $tmp_tag/a/#href
# Change the src of the unsupported image to that of the converted image created by the conversion service
#set_attr(src, $#//img/#src): $img
}
#remove: $tmp_tag
PHP script to convert the image
To handle the ICO files I used the IcoFileLoader library, I found it thanks to this question PHP GD .ico handling. I just took the PHP files from the src directory and put them directly on my hosting, so I had to use a simple Autoloader.
// The URL of the image to convert
// If the url of the image is relative, you have
// to build it here, example $url = 'https://gdude.de'.$_GET['url'];
$url = $_GET['url'];
// File name
$file_name = basename($url);
// Directory where the image will be saved
$dir = './';
// File location
$save_file_loc = $dir . $file_name;
// Open file
$fp = fopen($save_file_loc, 'wb');
// Download the image using CURL
$ch = curl_init($url);
// Set options for a cURL transfer
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
// Close file
fclose($fp);
// Load the image
// ICO images need special handling
if(str_ends_with($file_name, '.ico'))
{
require_once('Autoloader.php');
$loader = new IcoFileService;
// You must define the size, I did the tests with a 16X16 favicon.
$im = $loader->extractIcon($file_name, 16, 16);
}
else if(str_ends_with($file_name, '.webp'))
{
$im = imagecreatefromwebp($file_name);
}
// Check if the image was loaded
if(!isset($im))
{
die('Unable to load image!');
}
// Convert it to a png file
imagepng($im, $file_name.'.png');
imagedestroy($im);
// Delte the original image
unlink($file_name);
// "Return" the image in an HTML tag so that Instant View can handle it
echo '<img src="https://my-free-subdom.000webhostapp.com/' . $file_name . '.png">';
Feel free to improve the above code, perhaps add some security, delete old images, use other libraries or PHP functions, accept multiple images in the same request, etc.

I found imageoptim to be helpful for free conversion of (in my case) svg images. Just prepend this url to the svg url and they'll start to load. I chose a resolution of 2560 as it's the max resolution that IV 2.1 supports.
#set_attr(src, "https://img.gs/<your-username>/2560,fit,format=png,quality=high/", ./#src): $body//img[contains(#src, ".svg")]
#set_attr(srcset, "https://img.gs/<your-username>/2560,fit,format=png,quality=high/", ./#srcset): $body//img[contains(#srcset, ".svg")]

Related

How can I to read width, height, filesize of image in s3?

In laravel 8 uploading image to AWS S3 and I keep url in db table(I set visibility= 'public',
so I can show image in my browser by this saved url. Also I need to get width, height, filesize
of this file. When I use Storage in local I use Intervention\Image library with methods :
$file_width = Image::make($image_path)->width();
$file_height = Image::make($image_path)->height();
$file_size = Image::make($image_path)->filesize();
where $image_path - is path under my Storage.
With Object URL property my uploaded image has properties
S3 URI looking like
s3://app-s3/subdir/filepath.jpg
and Amazon Resource Name (ARN) :
arn:aws:s3:::app-s3/app-s3/subdir/filepath/31fzgzXsVTL.jpg
How can I to read width, height, filesize of image in s3 ?
MODIFIED BLOCK :
Reading at https://laravel.com/docs/8.x/filesystem#file-metadata link
example code:
use Illuminate\Support\Facades\Storage;
$size = Storage::size('file.jpg');
I try with get size with ‘s3’ driver:
$image_size = Storage::disk('s3')->size($cloud_url);
I got error :
File not found at path: https:/app-s3.s3.eu-central-1.amazonaws.com/app-s3/subdir/filepath/31fzgzxsvtl.jpg
As $cloud_url is common url, not path ...
From the docs looks like 'file.jpg' is PATH of the image in Storage directory. But I am not sure...
Thanks in advance!

Error Converting Apps Script Blob from PNG to JPEG

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.

How to add an image in TCPDF

I want to add an image in header using TCPDF in my Magento store.
I am doing this:
$tcpdf = new TCPDF_TCPDF();
$img = file_get_contents(Mage::getBaseDir('media') . '/dhl/logo.jpg');
$PDF_HEADER_LOGO = $tcpdf->Image('#' . $img);//any image file. check correct path.
$PDF_HEADER_LOGO_WIDTH = "20";
$PDF_HEADER_TITLE = "This is my Title";
$PDF_HEADER_STRING = "This is Header Part";
$tcpdf->SetHeaderData($PDF_HEADER_LOGO, $PDF_HEADER_LOGO_WIDTH, $PDF_HEADER_TITLE, $PDF_HEADER_STRING);
$tcpdf->Output('report_per_route_'.time().'.pdf', 'I');
What steps I have to follow if I want to add my store name (left corner) and logo (right corner)?
If you are trying to generate the pdf using the WriteHTML() here is a little trick to add image without use of image() function.
Simply use the HTML <img> as below,
$image_path = 'path/to/image';
$print = '<p>some text here...</p>';
$print .= '<img src=" '. $image_path .' ">';
and you can use inline css to apply height, width etc.
TCPDF is tricky about inserting images as HTML. It implements few hacks to tell what is being loaded:
inserting image with src attribute as absolute path - must have star * prefix:
<img src="*/var/www/my-image.png">
inserting image with src attribute as relative path - both examples are treated as relative paths:
<img src="/var/www/my-image.png">
<img src="var/www/my-image.png">
Note, that relative paths are calculated differently on linux and windows - what works correctly on windows may not work well on linux. That is caused by checking first character in a path string as a forward slash /, which is considered a linux root and the path will be recalculated - relative path will append to a global variable DOCUMENT_ROOT.
Loading base-64 encoded string - must have # prefix in src attribute:
<img src="#iVBORw0KGgoAAggfd0000555....">
<img src="#'.base64_encode(file_get_contents($path)).'" width=50 height=35>
This is safe bet if you want to avoid issues with calculating correct path, but adds extra I/O overhead, because TCPDF will attempt to store supplied data as temporary image file in order to determine image width & height.
Ok. First of all $PDF_HEADER_LOGO is suppose to be an image file name, not image data - as in default implementation of Header() function. There is, however, one important thing to remember, exact location depends on K_PATH_IMAGES constant, which should contain path to images folder. If its defined before including TCPDF library its ok, if not TCPDF checks some default paths and first existing is used as images directory. Those directories are:
./examples/images/
./images/
/usr/share/doc/php-tcpdf/examples/images/
/usr/share/doc/tcpdf/examples/images/
/usr/share/doc/php/tcpdf/examples/images/
/var/www/tcpdf/images/
/var/www/html/tcpdf/images/
/usr/local/apache2/htdocs/tcpdf/images/
K_PATH_MAIN (which is root tcpdf folder)
So either define constant before, or put your file to one of above directories, and then pass only file name as first argument to SetHeaderData and it should work.
To have something similar for Footer you need to extend base TCPDF_TCPDF class and overwrite its Footer method.
Example:
class MYPDF extends TCPDF_TCPDF {
// Page footer
public function Footer() {
// Position at 15 mm from bottom
$this->SetY(-15);
// Set font
$this->SetFont('helvetica', 'I', 8);
// Page number
$this->Cell(0, 10, 'COMPANY NAME', 0, false, 'C', 0, '', 0, false, 'T', 'M');
$this->Image('/path/to/image.jpg', 500)
}
}
You'll probably need to work out exact coordinates. Especially in Image it depends on your dimensions, you can add another parameter to Image function being y coordinate, and two others - width and height of image.
And most importantly I recommend checking great examples section on TCPDF page:
http://www.tcpdf.org/examples.php

Imagick: Issues reading file on Windows 64bit EasyPHP

I'm having a lot of difficulty working with PHP's Imagick class, it doesn't seem to want to read images regardless to the method I use.
Method 1
$handle = fopen('http://ima.gs/Placeholder-400x200.png', 'rb'); // Sample image
$img = new Imagick();
$img->readImageFile($handle);
$img->resizeImage(128, 128, 0, 0);
$img->writeImage(ROOT . DS . 'foo.png');
This gives me the Internal Error "Unable to read image from the filehandle"
Method 2 (Ideal Method)
$img = new Imagick(ROOT . DS . '00053141.jpg'); // Image does exist
$img->resizeImage(128, 128, 0, 0);
$img->writeImage(ROOT . DS . 'foo.jpg');
This gives me the Internal Error "no decode delegate for this image format `D:\Work\DittoCake\00053141.jpg' # error/constitute.c/ReadImage/550"
Configure List Results
You can see my delegates and configuration details here: http://cl.ly/image/1j2z1H072K41/Image%202014-10-22%20at%209.35.28%20AM.png
Command line convert results
convert 00053141.jpg -set colorspace RGB 00053141_rgb.jpg
This worked successfully and can confirm that the image mode was changed from CMKY to RGB when checking in Photoshop. (My last resort is to use shell_exec but I'd prefer not to)
I have a feeling this may be because I'm running it on Windows, my main goal in using this is just to convert any image from CMKY to RGB, resizing / changing image type is already covered in my application.

JavaScript load user's local image in browser after upload

I need to let user load one image from her local file system into the browser for some editing.
I don't wanna use flash or others. Only HTML and JavaScript.
So what I do is to let user upload the image to the server and the server returns the contents of the file (using php file_get_contents).
Now I have the contents of the image file as a string in JavaScript. I expected to assign this string to the src of an image element and it shows up. But when I assign it to src, nothing happens.
What's wrong? What's the solution?
src means an URL.
Either set that to an URL on the server, or use a Base64 encoded image:
PHP:
$imagedata = file_get_contents($file);
$encoded = base64_encode($imagedata);
echo $encoded;
JavaScript:
var imageElem = document.getElementById('image');
var filetype = 'png'; // Set file type here
imageElem.src = 'data:image/' + filetype + ';base64,' + image;

Resources