Converting PDF to PNG with same resolution - Imagemagick - file

I have 1000s of PDFs with multiple pages and each PDF has different resolution (based on scanners used to scan them). I want to convert each page of PDF to PNG to pass it to Tesseract for OCR. I used Imagemagick to convert to PNG but have to pass a fixed DPI for all images to get a good readable output. Is there a way I can convert each PDF by preserving the resolution of that PDF too?
For example, if 1.PDF has resolution 622 × 788 and 2.pdf has resolution 792 × 612, I want the exact conversion with same resoultion just a different format(PNG).
The command I am using right now is:
convert -monochrome -density 1200 input.pdf -resize 25% -monochrome -white-threshold 50% -black-threshold -50% output.png
Thanks,
pashah

Perhaps read the geometry of the first page, then resize all pages to match?
SIZE=$(identify -format '%g' input.pdf)
convert -monochrome \
-density 1200 \
-resize $SIZE \
-white-threshold 50% \
-black-threshold -50% \
-append \
output.png

Related

FFmpeg-wasm colorbalance filter always create washed out image, how to fix this?

I'm using FFmpeg wasm in the browser (React.js).
When I want to adjust the colors of a video using the colorbalance videofilter it always produces a washed out image.
await ffmpeg.run("-i", "test.mov", "-vf", "colorbalance=-0.4:-0.2:0.2:-0.4:-0.2:0.2:0:0:0.0", "-pix_fmt", "yuv420p", "test.mp4");
I'm usig the exact same command as in FFmpeg in my terminal (where it works correctly)
ffmpeg -i test.mov -vf colorbalance=-0.4:-0.2:0.2:-0.4:-0.2:0.2:0:0:0.0 -pix_fmt yuv420p output02.mp4
Has someone experienced the same issue?
Washed-out image attached

Getting an error 'too many inputs specified for the "scale" filter' in ffmpeg

I'm trying to add watermarks to multiple images using ffmpeg. It works good in the beginning but when I try to change the opacity of the watermark it shows the error as:
[AVFilterGraph # 0000019b2a655340] Too many inputs specified for the
"scale" filter. Error initializing complex filters. Invalid argument
The used code:
for %%a in ("*.jpg") do ffmpeg -i "%%a" -i wm.png -filter_complex "[1]lut=a=val*0.3[a];[0][a][1]scale=iw*0.50:-1[wm];[0][wm]overlay=0:0" -preset ultrafast "post\%%~na.jpg"
If I understand your intent correctly, change
[1]lut=a=val*0.3[a];[0][a][1]scale=iw*0.50:-1[wm];
to
[1]lut=a=val*0.3,scale=iw*0.50:-1[wm];
The watermarked can be scaled directly after the alpha change.

Compressed video:How to show B and P frames

I want to analyze a compressed video (h264).
I'm encoding using this command:
ffmpeg -i in_path -vf scale=340:256,setsar=1:1 -q:v 1 -c:v h264 -f
rawvideo out_path
now I want to see how the P&B frames look like, so I'm using this command in order extract only the b frames:
ffmpeg -ss 0 -i in_vid -t 2 -q:v 2 -vf
select="eq(pict_type\,PICT_TYPE_B)" -vsync 0 frameb%03d.jpg
The extraction went well, no errors, and the number of frames extracted makes since by theory.
But, I Don't know how to "show" the image, when I'm doing:
eog frameb001.jpg
I'm getting a normal picture and not what I expected from a B frame, now I understand why doing "eog" won't be good, but I have no idea how to "show" the frame so that it will be meaningful (saw some articles that use HSV to show the frame).
One more thing the fact that I got a meaningful image from the B frames, maybe the extraction wasn't good.
Any help will be great, Thanks a lot!

How to join pieces of images into one with using FFmpeg API?

I have parts of one image like
0x0_img1.jpg
100x200_img1.jpg
300x0_img1.jpg
360x420_img1.jpg
1080x720_img1.jpg
I just want to know how to merge these into a single image.
Image name has quadrants details (0x0 , 100x200... etc,.), which are the start position of the parts to the orginal image
Now how do I merge these parts of images using the FFMPEG c lib
You can use hstack filter here
ffmpeg -i 1.jpg -i 2.jpg -filter_complex hstack output

ffmpeg conversion - keep audio bitrate

I'm using ffmpeg to extract the audio from different video formats (flv, mp4) and convert it to mp3.
%~dp0ffmpeg.exe -i %1 -ar 44100 -ac 2 -ab 128k "%~dpn1.mp3"
This works just fine. However, in my input files, the audio bitrate varies, and I want to adjust the output bitrate accordingly. Even by extensive Google searching, I didn't find any hint how to just keep the original bitrate.
What I would need would be something like:
-ab copy
Which, of course, does not work.
Is there anything that will work?
P.S: As you might have figured from the formatting above, I'm using a windows batch file. There would be the hack to use %~dp0ffmpeg.exe -i, get the audio bitrate by grep and insert it in the command line. I just think there has to be an easier and more elegant way.
even though the original thread was looking for an answer without grepping anything, nate's script seems to be the most useful post. but it has some limitations, for example not all outputs give you a bitrate grepped, some turnout to give you just the result "default". here's a little more improved version of it.
#!/bin/env bash
ext=$1
for f in *.${ext}; do
x=${f%.*} ;
x=${x% - YouTube}; # I usually download some song covers from YouTube.
x=$x".mp3";
bit=`ffmpeg -i "${f}" 2>&1 | grep Audio | awk -F", " '{print $5}' | cut -d' ' -f1`
if [ -n "$bit" ]; then
ffmpeg -i "$f" -ab ${bit}k "$x"
else
ffmpeg -i "$f" "$x" # this is if we don't have an output from the grep line above, ffmpeg will keep the original quality, that is 192k for 192k
fi
done
Here is a bash script that will take a file extension and extract audio from any file with that extension, and of course maintain the bitrate. I can't claim the credit of the key piece of the code, as that goes to the gentleman that writes this blog.
#!/bin/bash
ext=$1
for file in *.${ext}; do
tmpfn=${file%.*} ; # get rid of file ext
tmpfn=$tmpfn".mp3"; # add mp3 file ext
# next line gets bitrate of audio from video using ffmpeg
bit=`ffmpeg -i "${file}" 2>&1 | grep Audio | awk -F", " '{print $5}' | cut -d' ' -f1`
# finally, convert to mp3 using proper bitrate
ffmpeg -i "$file" -ab ${bit}k "$tmpfn"
done
Just run it in the directory where you have the files like so:
$bash script.sh flv
where flv is the file extension. Hack it to make it do exactly as you wish or process multiple filetypes to your heart's content.
EDIT: Just a quick note for anyone on Ubuntu/debian/etc. Make sure you install the additional codec package or else it won't work, i.e. you must install ffmpeg and the extra libav codec package or you're gonna have a bad time. This should do the trick:
sudo apt-get ffmpeg libavcodec-extra-53
As LordNeckbeard states, using the same bitrate to encode in different formats isn't necessarily wise. However...
Here is a batch-file solution which captures the input file bitrate and uses that as a parameter for the encoding command line. This approach was hinted at by the original questioner. The mp3 output file is created in the same folder as the input file.
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
REM Usage: scriptname.cmd "full-quoted-path-to-input-file"
REM Adjust FFMPEG_PATH variable value to match the path to your FFMPEG binary
SET FFMPEG_PATH=C:\Program Files\ffmpeg-20170807-1bef008-win64-static\bin
SET INPUT_FILE_FULL_PATH=%1
REM Get input file bitrate
FOR /F "tokens=5 delims==," %%i IN ('""%FFMPEG_PATH%\ffmpeg.exe" -i %INPUT_FILE_FULL_PATH% 2>&1 | find "Audio:""') DO (
FOR /F "tokens=1 delims==k" %%j IN ('ECHO %%i') DO (
SET BITRATE=%%j
SET BITRATE=!BITRATE: =!
ECHO Input file bitrate is !BITRATE! kb/s
)
)
REM Encode file using previously captured bitrate
"%FFMPEG_PATH%\ffmpeg.exe" -i %INPUT_FILE_FULL_PATH% -ar 44100 -ac 2 -ab !BITRATE!k "%~dpn1.mp3"
There is scope for tightening the code up, for example, a check to make sure at least one argument was provided, and that the BITRATE is not empty before beginning the encode, but as a rough and ready solution this should do fine.
Current version of ffmpeg (tested 2.1.4) recommends using "-qscale 0" to preserve quality. This worked for me on my mpeg4 video test file.
Try this option: -codec copy or -acodec copy for only audio.
Check this reference http://ffmpeg.org/ffmpeg.html#Stream-specifiers-1
Instead of
-ab copy
try
-sameq
%~dp0ffmpeg.exe -i %1 -sameq "%~dpn1.mp3"

Resources