Replace an image in Google Slides with Apps Script with same croping - google-apps-script

I'm trying to replace an image in a Google Slide by a smaller version of it (in terms of bytes).
The smaller image should be displayed exactly the same way than the older.
But when my original image was croped, I cannot reproduce it with the new one.
What I'm doing is simple (I'm using this replace method)
let image = page.getImages()[0];
let newImageUrl = optimize(image.getContentUrl()); // API call to get an optimized image. newImage will have the same width and height
image.replace(newImageUrl, true);
A visual example.
Here is my slide before (pay attention to the "Quick" logo at the bottom right corner)
And here is the result after replacing it (you can see that the bounding box is the same, it takes the same space in the slide, but the image itself is lower)
How can I reproduce the croping that I've initially done in my slide with that button ?
Thanks

Issue:
As mentioned in comments, crop properties are currently read-only, so this cannot be done. Here are possible workarounds: https://stackoverflow.com/a/63256489, https://stackoverflow.com/a/64040404, https://stackoverflow.com/a/67309702.
Feature request:
There's a feature request in Issue Tracker. Anyone interested in this, consider starring it:
Why are Image Crop Properties read only

Related

gizmo based on Three.js is not visible

I created Forge viewer app w/ Transformation Extension based on GitHub sample "forge-extensions", for unknown reason, gizmo is not visible after I click on element, only very small yellow dot after zoom in, I believe it's element center point and gizmo size is too small, so my question is how to control it? in fact, all the coding is copied from that GitHub sample "forge-extensions", I must miss something simple!
Have you tried your code with different types of models, and does it behave the same for all of them? I believe it may have something to do with the scale of the particular model, especially when looking at these lines of code from the viewer extension:
_transformControlTx.setSize(
bbox.getBoundingSphere().radius * 5);
Try and put a breakpoint there, and see what the radius is. Or try adjusting the hard-coded value.

Extract image from web page

How to extract the image from this https://www.google.com/maps/#45.8118462,15.9725486,3a,75y/data=!3m7!1e2!3m5!1sAF1QipOH6lgU7bug2ndyW-9-Uq0kgKqcKDtnGei2N5Qo!2e10!6shttps:%2F%2Flh5.googleusercontent.com%2Fp%2FAF1QipOH6lgU7bug2ndyW-9-Uq0kgKqcKDtnGei2N5Qo%3Dw150-h150-k-no-p!7i3024!8i4032
(If the link disappears let me describe how to reproduce the question. Find any shop on Google Maps that has the "shop title image" appearing in the shop details on the left side when you click on that shop. Click on that image to expand it across the whole viewport.)
I found the <canvas> element that I guess contains the image. I tried to do .getContext('2d') on that canvas element, but I keep getting null.
If you are getting null when doing getContext("2d") it's because an other type of context was created already, in this case, a "webgl" one.
To convert that canvas to a new image, you'd normally call canvas.toBlob() (whatever the context type).
And if you need to crop that canvas content, you'd draw it on an other canvas.
But since they did not prevent the WebGL context to throw away its drawing buffer (by passing preserveDrawingBuffer in the getContext call), you'll only get a transparent image back from it.
Anyway none of these methods will retrieve the original image, but they will create a new image entirely (probably of lesser quality, and bigger in size). To retrieve the original image, check the network tab of your dev tools, or if you need to do it programmatically, inject a script that will spoof all fetch, XHR and HTMLImageElement objects in order to log their resource URL. But that becomes dirty.

How do I make my html gif unloop? [duplicate]

I have an animated gif in an img tag that I start by rewriting the src attribute. The gif was created, though, to loop and I only want it to play once. Is there a way, with Javascript or jQuery, to stop an animated gif from playing more than once?
I was having the same problem with an animated gif. The solution is rather simple.
Open the Animated gif in Photoshop.
Go to the Window tab and select timeline(if the timeline is not already open).
At the bottom of the timeline panel, you will find an option, which says "Forever".
Change that to "Once".
Go to File> Export> Export for Web and save it as a gif.
That should do it.
can you find out how long the gif takes to loop once?
if so then you can stop the image like this:
pseudocode:
wait until the end of the image (when it is about to loop)
create a canvas element that has a static version of the gif as currently displayed drawn on it
hide gif
display canvas element in a way that makes it look like the gif froze
javascript:
var c = $("canvas")[0];
var w = c.width;
var h = c.height;
var img = $("img")[0];
setTimeout(function () {
c.getContext('2d').drawImage(img, 0, 0, w, h);
$(img).hide();
$(c).show();
},10000);
jsfiddle
edit:
I forgot to add reference to the original answer that I took this from, sorry
Stopping GIF Animation Programmatically
that one doesn't address the time factor you need for only one loop
Also, it has been mentioned that this approach is problamatic in certain cases (It actually didn't work when I try it in firefox right now...). so here are a few alternatives:
mentioned by Mark: edit the gif itself to avoid looping. this is the best option if you can.
but I've run into cases where it was not an option (like automated generation of images by a third party)
instead of rendering the static image with canvas, keep a static image version and switch to stop looping . this probablyhas most of the problems as the canvas thing
Based on this answer, it's kinda expensive, but it works. Let's say a single loop takes 2 seconds. At a setTimeout after 2 seconds kick in a setInterval, that would reset image source every millisecond:
setTimeout(function() {
setInterval(function() {
$('#img1').attr('src',$('#img1').attr('src'))
},1)
}, 2000)
again, probably just a proof of concept, but here's demo: http://jsfiddle.net/MEaWP/2/
Actually it is possible to make a gif to stop after just one iteration or any specific number of iterations, see an example below (if it is not already stopped), or in jsfiddle.
To do that the gif must be created with number of iterations specified. This could be done using Screen to Gif, it allows to open a gif or a bunch of images and edit it frame by frame.
This solution also allows you to reset the animation by imgElem.src = imgElem.src; but this does not work in MS IE/Edge.
Jurijs Kovzels's answer works in some condition but not in all.
This is browser-dependent.
It works well with Firefox. But In Google Chrome and Safari, it does not work if the gif is on the same server. The example he provided works because the gif is on the external server.
To restart gifs stored on the internal server, using Google Chrome and Safari, you need extra steps to make it work.
const img = document.getElementById("gif");
img.style = "display: none;";
img.style = "display: block;";
setTimeout(() => {
img.src = img.src;
}, 0);
This is inspired by this answer.
Not sure if this is the best way to respond to everyone and have it appear after all the previous answers and comments, but it seems to work.
I don't have much control over the gif. People post whatever gif they want as the "thankyou.gif in their account directory and then the ThankYou code runs whatever they've put there when a comment is submitted to a form they've posted. So some may loop, some may not, some may be short, some may be long. The solution I've come to is to tell people to make them 5 seconds, because that's when I'm going to fade them out, and I don't care if they loop or not.
Thanks for all the ideas.
I know I am pretty late here but..here it is...
I don't know if you would go to this length but let me share a trick.
Open the GIF in Macromedia Flash 8(it has deprecated since then), Export the GIF as Animated GIF. You will have to choose the file location. After that you would receive a dialog box with settings. In that, add the number of times you want the animation to happen. Click OK. Problem solved.

How to capture an image of an HTML element, and maintain transparency?

I'm working on a page that will allow a webmaster to add styles to their twitter feed. Several of these styles use transparency in their display. I want to create a list of images for them to choose from. Currently I am taking screenshots on a checked background such as this:
But that isn't really what I want.
Is their some method of capturing an image of an HTML element, and maintaining the transparency?
EDIT: I'm just digging into this, so I'm coming across new topics, such as HTML5 Canvas, and -moz-element. Is it possible to set a canvas background to the html element using -moz-element, then extract the image data from the canvas? I'm going to try this unless someone who's 'been there done that' heads me off.
EDIT: The -moz-element and canvas was a deadend. -moz-element will set the item as a background, but will not allow you to save background image. And canvas doesn't save its background, even when the background is a normal image.
It requires a little bit of work, but it is doable, as long as it's HTML you're laying out. You can't recover the transparency of markup in pages you've downloaded without saving those pages and editing them locally. By rendering the HTML elements multiple times, on different background colors, the opacity can be derived using an image editor. You're going to need a decent image editor, I use GIMP.
Render the elements you want to save three times, on a black, a white and a neutral gray background(#888).
Using a screen capture program, capture those displays and crop them to the exact same areas.
In GIMP open those images as layers and order them black, white and gray, top to bottom.
Set the top, black layer to difference mode. This will give a grayscale difference between the black and white layers.
Merge down the top layer. This will leave us with two layers. The gray background layer and the grayscale difference. Invert the colors of the difference layer, and copy it to the clipboard.
Add a layer mask to the gray background layer and paste the clipboard into the layer mask.
Delete the grayscale layer and apply the layer mask on the gray background layer. That should leave one layer with opacity similar to the original.
The opacity is off by a bit, but if we duplicate the layer and merge it with itself, it's right in the ballpark.
It's probably not pixel perfect, but it is proof of concept. Opacity of HTML markup can be captured.
Using Puppeteer makes this much easier to do. It runs a web-page in-memory.
Start a local fileserver - python -m SimpleHTTPServer 8080
Then this script should do the trick:
const puppeteer = require('puppeteer')
;(async () => {
const browser = await puppeteer.launch()
const page = await browser.newPage()
await page.goto('http://localhost:8080/index.html', {
waitUntil: 'networkidle0'
})
const elements = await page.$('body')
await page.evaluate(() => (document.body.style.background = 'transparent'))
await elements.screenshot({ path: 'myImg.png', omitBackground: true })
await browser.close()
})()
the docs for .screenshot() are here.
What you'd need is a web browser that can render into an image buffer in memory instead of the screen.
My guess is that all browsers can do this (that should be part of the renderers) but I'm not aware of any browser where you can access this function, at least not from JavaScript.
If you download the WebKit sources, there should be test cases which do something like that :-/
No, there's no software that will allow you to take screenshots and preserve the transparency of individual visual elements as a transparent spot in the image, because that's not how a screenshot works - screenshots are WYSIWYG, by definition, all elements in your screenshot will always have a non-transparent background.
I think your best bet here is to recreate the desired portion as an image, where you can control the transparency normally. It's not the best solution, but if you're doing this a lot with the same kinds of things, it will be much faster for you rather than cropping/editing screenshots.

How to capture zoomable image as one high resolution image?

I would like to capture a zoomable image at a high resolution zoomed at 3x. Do you know of a way I can piece this image together without having to do it manually? Here is the image
After using bhups' solution, tweaking outputxand outputy for a good while, I tried something else.
I went back to the object page (in the above example, here), took the thumbnail image URL (http://www.metmuseum.org/Imageshare/ep/regular/DP145931.jpg), replaced regular with zoom and to my surprise got what I presume is the full image, with less effort:
http://www.metmuseum.org/Imageshare/ep/zoom/DP145931.jpg
You can tweak the URL to get the job DONE. Here is the URl for 3x image. http://media.metmuseum.org/mgen/metzoom/zoom3.ms?img=DP145931.jpg&wrapperid=11&outputx=1200&outputy=1601.067378252168&level=1&x=0&y=0&backcolor=0x00000
outputx and outputy are the output image dimensions. level implies the zoom level. and x and y are the top left corner of the selected rectangle.