FFMPEG, Blur an area of a video using Image Select Areas Plugin - javascript

I am building an online video editor. I need to allow the users to blur an area of movies. This must be done graphically, I mean user should be able to select an area of a video, using an screenshot, then the selected area must be blurred. Some thing like this
Is there anyway to map this selected area dimension and its distance from borders to the real values that must be applied to the video?
I mean four numbers, width, length, top, left will be provided using this plug in and I need to use these numbers to blur an area of videos.
I take an screenshot of video. In order to keep the aspect ratio, I will fix the width to 800px and let the height to be scaled up/down. It is clear that the width, length, top, left of the selected area of the screenshot is a factor of the width, length, top, left of the area that must be blurred in video. but I don't know how to get this factor. Besides that I don't know how to get the video resolution.
Thanks in advance.
Update
This is my PHP code that gets the selected area dimensions and offsets
$iLeft = $_POST['left'];
$iTop = $_POST['top'];
$iWidth = $_POST['width'];
$iHeight = $_POST['height'];
exec('ffmpeg -i '.$url.' -filter_complex "[0:v]scale=iw*sar:ih,setsar=1,split[bg][bb];[bb]crop='.$iWidth.'*iw/800:iw*'.$iHeight.'/800:'.$iWidth.'*iw/800:'.$iHeight.'*iw/800,boxblur=10[b0];[bg][b0]overlay='.$iLeft.'*W/800:'.$iTop.'*W/800"" '.$name.' > block.txt 2>&1');
$iLeft, $iTop, $iWidth, $iHeight are the left, top, width and height of the selected area via the image plugin.
It blurs many selected areas very well, but areas like this
The Image Left, Top, Width, Height is 257, 39.26666259765625, 10, 391
don't get blurred. Also a video with Dimension 207x207 didn't get blurred as well.

Running
ffprobe in.mp4 -loglevel quiet -select_streams v -show_entries stream=width,height,sample_aspect_ratio -of compact=p=0:nk=1
will produce an output that looks like this:
1280|720|1:1
The first entry is the video width, then the height, and finally the pixel or sample aspect ratio, shown as num:den so it's num/den. That's your video resolution.
With that info, the factor is video-width*sar/800. This assumes that you'll be scaling all anamorphic videos to square pixels using the scale and setsar filters, and that the 800px screenshot is undistorted as well. If you're using FFmpeg to scale screenshot, it's scale=800:ih*800/iw/sar
So FFmpeg value for area width is screenshot area width * video-width*sar/800.
and for FFmpeg Y co-ordinate is screenshot top * video-width*sar/800, and so on.
Assuming the code in the comment is for the screenshot, for the full-sized movie, it would be
"[0:v]scale=iw*sar:ih,setsar=1,split[bg][bb];[bb]crop=50*iw/800:50*iw/800:20*iw/800:10*iw/800,boxblur='min(min(cw/2\,ch/2)\,10)'[b0];
[bg][b0]overlay=20*W/800:10*W/800"
I've scaled the movie to make sure we're always dealing with a square-pixel video.

Related

Align image in canvas if image width is bigger than canvas

I have an image which has a ratio of 1724:1078(width:height).
Now i need to center that image inside canvas which is 800:1078.
This scenario works perfect with the code bellow:
ctx.drawImage(this.leftImageResized, ((this.thumbnailWidth/2)-this.leftImageResized.width)/2, (this.thumbnailHeight-this.leftImageResized.height)/2);
But what i cannot figure out is how to position the image to the left of the canvas and to the right of the canvas, because the image is wider than the canvas itself.
What i basically need to achieve is placing the left side of the image in the beginning of the canvas and in the second scenario placing the right side of the image to the right side of the canvas.
I already tried the code bellow to position it to the left:
ctx.drawImage(this.leftImageResized, 0, 0);
But this code does not work as expected. Basically it crops out a part of the image, although the image is positioned to the left a part of the image to the left is outside of view...
EDIT: This question has not a single point common with the question pointed as a duplicate, i am not simulating a cover at all, at the contrary my image should be cut but in different context.
As you can see on the image bellow this scenario is the one i need to cover, the image can be much bigger, but i need it aligned to the left edge of the canvas and also to the right edge.
If I understand correctly here is a schema of your situation:
leftImageResized
|------------------|
canvas
|----|
=> left margin
|------|
If this representation is correct, the width of your left margin equals
(width image - width canvas) / 2
And thus replacing
((this.thumbnailWidth/2)-this.leftImageResized.width)/2
by
-(this.leftImageResized.width - this.thumbnailWidth)/2
Should solve it

Scale objects after loadFromJson

Let's say I'm working on a 1000x1000 px fabric canvas. I add an 200x200px image right in the middle (top: 400, left: 400), then save my canvas as json. (the bag on these pictures is a background image, don't mind it)
I create another canvas, which is smaller. If I load my json, image will still be 200x200px, and 400px from top and left, therefore getting out of my canvas.
How can I make sure that, once loaded in a smaller/bigger canvas, my objects will scale accordingly ?
Work out the new canvas dimensions as a percentage of the original canvas then set the scale on each of the items in the callback of loadJSON.
As in your example if original canvas was 400x400, new one is 200x200 then scale is 0.5. Apply that to each object in the callback of loadJSON and to its coordinates (top, left etc etc).

How to convert points to pixels to scale properly

I'm trying to do and image highlight. So I take pdf image preview and based on the field (extracted from pdf) the user clicks, it will highlight the field in the image preview.
Im trying to accomplish this using css where a have rectangle at the bottom of the image and just set a margin based on the field position that will highlight that field in the pdf image preview.
The problem is that I can't quite get the conversion right for my margins.
So I know there 72pt in an inch and 96 pixels in an inch.
Don't really know where to take it form there. Should I also consider the user's resolution? Is there a library I can use?
So far what I have given:
field positions (in points),
pdf max height/width (in points),
image preview max height/width (in pixels)
How can I convert the field position to pixels so I can highlight that field in the image preview?
Convert points to pixels.
pdfPointsH / pdfPixelsH = x
pdfPointsW / pdfPixelsW = y
Use proportion to translate Point coordinates into Pixel coordinates e.g.:
PointX * x = PixelX
PointY * y = PixelY
Hope that helps.

Change the origin when resizing and moving an image

I am trying to make an image resizer and cropper, but am having trouble with resizing it from a desired point.
Currently, you can resize (just changing the with+height of an <img> element) and move around the image (offsetting the top and left margins of the <img> element). The problem is once you move it and resize it again, it does so from the center of the image. I would like it to resize relative to the center of the crop window.
Here is an image of what I currently have (top) and what it should be like (bottom):
http://i.imgur.com/eAE4IEF.jpg
I have been unable to figure out the math of how to resize it and then move it so the origin is not in the center of the image, but in the center of the red window.
I would appreciate any help with this.
This is essentially scaling an individual point inside the image (the center of the crop box) by the given scale factor, which involves multiplying each of the coordinates of the point by that factor.
new_center_x = old_center_x * new_image_width/old_image_width
new_center_y = old_center_y * new_image_height/old_image_height
http://jsfiddle.net/jDXHz/5/
You can then shift both the image and the box back by the difference between the new and old position to keep the box stationary while the image scales around it.

Measure area inside of image - is it possible?

Situation:
Got png (or bmp) image inside html file, on image there are black rectangles on white background. Image size is always constant AxB, rectangles are not rotated and are different each time. Html file and images are generated automatically by some software as a job report.
I need to measure area (in square pixels) of that rectangle i point and click with mouse.
I imagine it this way:
Image is loaded into array or something, when i click image, desired function perform following tasks:
find nearest black pixels to the left, right, up and down, (searching through array from coordinates i click with cursor)
calculate size of rectangle (based on those black pixels),
calculate area,
return area to some variable.
Now, is it even possible? Is there maybe another method? I'm thinking about js solution since i'm not familiar with jquery at all; php and server-side solutions are not an option since the html files are standalone files on local drive.
Thank you in advance
----------------edit-------------
Images to process are black&white (always 1bit!) and look like here.
http://www.dropbox.com/s/smh4982om3hkhd8/job_report_image1.png
I know that first rectangle marked with red "1." has size of 542x570px (inside) - so area is 308940 square pixels - i measured it with MS Paint ;) - now i want to achieve the same in browser - click inside this rectangle and get the same result.
Not an implementation but more a way to go with javascript and HTML5:
Import your image in a 2d canvas context
get the coordinates in the canvas where the mouse click occured
then using canvas getImageData and go through them to get surrounding black pixel
more info on getImageData here: http://www.html5canvastutorials.com/advanced/html5-canvas-get-image-data-tutorial/
If I understand true, you want to calculate area of an image.
here is a working sample. If you need to calculate with borders you should use myitem.clientHeight * myitem.clientWidth else myitem.offsetWidth*myitem.offsetHeight
function calculate(myitem) {
alert(myitem.clientHeight * myitem.clientWidth);
alert(myitem.offsetWidth*myitem.offsetHeight)
}
This might be little useful for you to find the area: (using php)
<?php
$img = imagecreatefrompng('http://img87.imageshack.us/img87/5673/rotatetrans.png');//open the image
$w = imagesx($img);//the width
$h = imagesy($img);//the height
//Convert to centimeter
$dpi = 300;
$h = $h * 2.54 / $dpi;
$w = $w * 2.54 / $dpi;
echo "width is:".$w;
echo "Height is:".$h;
$area = $w * $h;
echo "Area is:".$area;
?>
Edit:
The number of pixels in an image is simply the height multiplied by the width.
Demo Here>>

Categories