I'm attempting to increase a very low resolution jp2 image to a higher DPI so that the image can been seen without any inconvenience to our eyes.
I have been successful in reading a jpeg2000 encoded string and displaying it as a PNG file. (Below is the code)
$imagedata = "AAAADGpQICANCocKAAAAFGZ0eXBqcDIgAAAAAGpwMiAAAAAtanAyaAAAABZpaGRyAAAAyAAAAKAAAwcHAAAAAAAPY29scgEAAAAAABAAAAGXanAyY/9P/1EALwAAAAAAoAAAAMgAAAAAAAAAAAAAAKAAAADIAAAAAAAAAAAAAwcBAQcBAQcBAf9SAAwAAAABAQUEBAAA/1wAI0JvGG7qbupuvGcAZwBm4l9MX0xfZEgDSANIRU/ST9JPYf9kACIAAUNyZWF0ZWQgYnk6IEpKMjAwMCB2ZXJzaW9uIDQuMf+QAAoAAAAAAQMAAf9SAAwAAAABAQUEBAAA/5PPoKgT/dHUscn3uMJWDWKb153z8hPvSInB8QsdvHSg4pzoLevV6cHhwCOWrDWed1zB8RKHyC4PEhigx/MYuIx4wci8q/CEo2kiHBrV8DhszG7ymZ/UH7atm39cdbppgIDD4VYfCrB00E+GI+Qf3v1IHzVdC6k/pMRXolANASf+TQYCTKERfZoHB65rCU23EcMzjiQo+2MAmLli7aos4tyAgMOrw6tBVpk5rPA9rz1HB6Wn+siLUizMFl3TKpn7s1pJGcCba3pGnanMUNO8OP+EwaMdppACpwb6vbqSpeUbgICAgICAgID/2Q==";
$image=base64_decode($imagedata);
// Create Imagick object
$im = new Imagick();
// Convert image into Imagick
$im->readImageBlob($image);
//Set the output format
$im->setImageFormat("png");
header('Content-type: image/png');
echo $im;
I read it is a possibility to increase the DPI using ImageMagick. See here http://www.imagemagick.org/discourse-server/viewtopic.php?t=18241
How do I achieve this in my PHP script (NOT through command line) ? Any help and guidance would be very much appreciated.
If you look at the UK Government website for the Passport Office, it says that passport photos need to be at least 600px wide by 750px tall.
Let's start with a photo of adequate quality (if not content) for Mr Bean at 600x750:
If we now resize him down to the same as your image (160x200), then back up you will see the quality has suffered through trying to represent the image at 160x200 and you can't invent all those pixels you lost - they are gone for good. Look at his teeth and the highlights in his eyes:
convert bean.jpg -resize 160x200 -resize 600x750 result.jpg
So, all you can do in Imagick is:
Imagick::resizeImage ( int $columns , int $rows , int $filter , float $blur [, bool $bestfit = FALSE [, bool $legacy = FALSE ]] )
to go back up to 600x750 and experiment with setting the filter to Catrom or Lanczos. But you can't invent stuff that isn't there...
Related
I am new to Python and am trying to parallelize a program that I somehow pieced together from the internet. The program reads all image files (usually multiple series of images such as abc001,abc002...abc015 and xyz001,xyz002....xyz015) in a specific folder and then combines images in a specified range. Most times, the number of files exceeds 10000, and my latest case requires me to combine 24000 images. Could someone help me with:
Taking 2 sets of images from different directories. Currently I have to move these images into 1 directory and then work in said directory.
Reading only specified files. Currently my program reads all files, saves names in an array (I think it's an array. Could be a directory also) and then uses only the images required to combine. If I specify a range of files, it still checks against all files in the directory and takes a lot of time.
Parallel Processing - I work with usually 10k files or sometimes more. These are images saved from the fluid simulations that I run at specific times. Currently, I save about 2k files at a time in separate folders and run the program to combine these 2000 files at one time. And then I copy all the output files to a separate folder to keep them together. It would be great if I could use all 16 cores on the processor to combine all files in 1 go.
Image series 1 is like so.
Consider it to be a series of photos of the cat walking towards the camera. Each frame is is suffixed with 001,002,...,n.
Image series 1 is like so.
Consider it to be a series of photos of the cat's expression changing with each frame. Each frame is is suffixed with 001,002,...,n.
The code currently combines each frame from set1 and set2 to provide output.png as shown in the link here.
import sys
import os
from PIL import Image
keywords=input('Enter initial characters of image series 1 [Ex:Scalar_ , VoF_Scene_]:\n')
keywords2=input('Enter initial characters of image series 2 [Ex:Scalar_ , VoF_Scene_]:\n')
directory = input('Enter correct folder name where images are present :\n') # FOLDER WHERE IMAGES ARE LOCATED
result1 = {}
result2={}
name_count1=0
name_count2=0
for filename in os.listdir(directory):
if keywords in filename:
name_count1 +=1
result1[name_count1] = os.path.join(directory, filename)
if keywords2 in filename:
name_count2 +=1
result2[name_count2] = os.path.join(directory, filename)
num1=input('Enter initial number of series:\n')
num2=input('Enter final number of series:\n')
num1=int(num1)
num2=int(num2)
if name_count1==(num2-num1+1):
a1=1
a2=name_count1
elif name_count2==(num2-num1+1):
a1=1
a2=name_count2
else:
a1=num1
a2=num2+1
for x in range(a1,a2):
y=format(x,'05') # '05' signifies number of digits in the series of file name Ex: [Scalar_scene_1_00345.png --> 5 digits], [Temperature_section_2_951.jpg --> 3 digits]. Change accordingly
y=str(y)
for comparison_name1 in result1:
for comparison_name2 in result2:
test1=result1[comparison_name1]
test2=result2[comparison_name2]
if y in test1 and y in test2:
a=test1
b=test2
test=[a,b]
images = [Image.open(x) for x in test]
widths, heights = zip(*(i.size for i in images))
total_width = sum(widths)
max_height = max(heights)
new_im = Image.new('RGB', (total_width, max_height))
x_offset = 0
for im in images:
new_im.paste(im, (x_offset,0))
x_offset += im.size[0]
output_name='output'+y+'.png'
new_im.save(os.path.join(directory, output_name))
I did a Python version as well, it's not quite as fast but it is maybe closer to your heart :-)
#!/usr/bin/env python3
import cv2
import numpy as np
from multiprocessing import Pool
def doOne(params):
"""Append the two input images side-by-side to output the third."""
imA = cv2.imread(params[0], cv2.IMREAD_UNCHANGED)
imB = cv2.imread(params[1], cv2.IMREAD_UNCHANGED)
res = np.hstack((imA, imB))
cv2.imwrite(params[2], res)
if __name__ == '__main__':
# Build the list of jobs - each entry is a tuple with 2 input filenames and an output filename
jobList = []
for i in range(1000):
# Horizontally append a-XXXXX.png to b-XXXXX.png to make c-XXXXX.png
jobList.append( (f'a-{i:05d}.png', f'b-{i:05d}.png', f'c-{i:05d}.png') )
# Make a pool of processes - 1 per CPU core
with Pool() as pool:
# Map the list of jobs to the pool of processes
pool.map(doOne, jobList)
You can do this a little quicker with libvips. To join two images left-right, enter:
vips join left.png out.png result.png horizontal
To test, I made 200 pairs of 1200x800 PNGs like this:
for i in {1..200}; do cp x.png left$i.png; cp x.png right$i.png; done
Then tried a benchmark:
time parallel vips join left{}.png right{}.png result{}.png horizontal ::: {1..200}
real 0m42.662s
user 2m35.983s
sys 0m6.446s
With imagemagick on the same laptop I see:
time parallel convert left{}.png right{}.png +append result{}.png ::: {1..200}
real 0m55.088s
user 3m24.556s
sys 0m6.400s
You can do that much faster without Python, and using multi-processing with ImageMagick or libvips.
The first part is all setup:
Make 20 images, called a-000.png ... a-019.png that go from red to blue:
convert -size 64x64 xc:red xc:blue -morph 18 a-%03d.png
Make 20 images, called b-000.png ... b-019.png that go from yellow to magenta:
convert -size 64x64 xc:yellow xc:magenta -morph 18 b-%03d.png
Now append them side-by-side into c-000.png ... c-019.png
for ((f=0;f<20;f++))
do
z=$(printf "%03d" $f)
convert a-${z}.png b-${z}.png +append c-${z}.png
done
Those images look like this:
If that looks good, you can do them all in parallel with GNU Parallel:
parallel convert a-{}.png b-{}.png +append c-{}.png ::: {1..19}
Benchmark
I did a quick benchmark and made 20,000 images a-00000.png...a-019999.png and another 20,000 images b-00000.png...b-019999.png with each image 1200x800 pixels. Then I ran the following command to append each pair horizontally and write 20,000 output images c-00000.png...c-019999.png:
seq -f "%05g" 0 19999 | parallel --eta convert a-{}.png b-{}.png +append c-{}.png
and that takes 16 minutes on my MacBook Pro with all 12 CPU cores pegged at 100% throughout. Note that you can:
add spacers between the images,
write annotation onto the images,
add borders,
resize
if you wish and do lots of other processing - this is just a simple example.
Note also that you can get even quicker times - in the region of 10-12 minutes if you accept JPEG instead of PNG as the output format.
thanks for stopping by.
I am trying to process ~50 images from .nd2 to .TIF, but the exported images are not what I expect and I'm not sure what is wrong. My .nd2's have two channels and I would like the final .TIF to be an image of both channels. However, the .TIF output of my code is an image of just one channel.
setBatchMode(true); //Batch mode processing setting in ImageJ
for (i=0; i<list.length; i++) {
showProgress(i+1, list.length);
filename = list[i];
setBatchMode(true); // prevents image windows from opening while the script is running
run("Bio-Formats Windowless Importer", "open=[" + dir1 + filename +"] autoscale color_mode=Composite rois_import=[ROI manager] view=DataBrowser stack_order=XYCZT");
selectWindow(filename);
run("Stack to RGB", "slices"); // convert to RGB stack
...after this part of code I split the z-stack, find the middle, and save that slice as a .TIFF.
Please let me know if anything isn't clear. Thanks again for reading.
I am using a Nikon D5200. I intend to do some image processing on the raw images shot with the camera. But I am encountering a problem when I read the raw images using GNU Octave. Rather than giving bit depth of 16 (since the .NEF are shot at 14-bit depth), the result is just a 8-bit array. What might be the problem?
imfinfo("/media/karthikeyan/3434-3531/DCIM/100D5200/DSC_1094.NEF")
ans =
scalar structure containing the fields:
Filename = /media/karthikeyan/3434-3531/DCIM/100D5200/DSC_1094.NEF
FileModDate = 10-Oct-2016 18:10:02
FileSize = 26735420
Format = DCRAW
FormatVersion =
Width = 6036
Height = 4020
BitDepth = 8
ColorType = truecolor
The result from exiftool is as follows:
exiftool DSC_1094.NEF | grep -i bit
Bits Per Sample : 14
I am using Ubuntu 14.04, Octave 4.0.3.
In this post, i was wondering why my png files were badly displayed on retina displays.
I finaly found that the problem came from the PNG file itself: when I open it and save it again with photoshop or something else, the problem disapear.
As this post proposed, I used sips command to see what exactly were formed my PNG file. I have the original-image.png (with the glitch) and the photoshoped-image.png
The command
sips original-image.png -g all
Gives me
pixelWidth: 256
pixelHeight: 256
typeIdentifier: public.png
format: png
formatOptions: default
dpiWidth: 72.000
dpiHeight: 72.000
samplesPerPixel: 3
bitsPerSample: 8
hasAlpha: no
space: RGB
And
sips photoshoped-image.png -g all
Gives me
pixelWidth: 256
pixelHeight: 256
typeIdentifier: public.png
format: png
formatOptions: default
dpiWidth: 72.000
dpiHeight: 72.000
samplesPerPixel: 4
bitsPerSample: 8
hasAlpha: yes
space: RGB
profile: HD 709-A
So 3 differences :
samplePerPixel
hasAlpha
the photoshoped file has a profile.
But these properies are read-only in sips and I wonder how can I change them to understand exactly where the bug comes from.
Any idea ?
So using sips you can output a different file. Take the photoshop file and start modifying it. First remove the profile, then remove the alpa channel (which will affect the first two variables).
Its quite possible that this image works. PNG has many options, and the original image may have some other feature not visible using these tools. Photoshop is obviously re-writing the image completely, using the RGB values as the only common attribute between the files.
I suspect that when you do the above, that image will work too. There is just something odd about the originals.
In any case, you make it easier on iOS if you use pngs with an alpha channel, as it will convert them to have one if the base image does not have one.
On some files, this works:
sips -s format png '/Volumes/HD/Optimized PNG/TXT - Section Depth copy.png' --out '/Volumes/HD/Optimized PNG/TXT - Section Depth copy-.PNG'
/Volumes/HD/Optimized PNG/TXT - Section Depth copy.png
/Volumes/HD/Optimized PNG/TXT - Section Depth copy-.PNG
mis-bhayward61p-swk:~ zav$
But also, sometimes it doesn't:
sips -s format png --setProperty hasAlpha 0 '/Volumes/HD/Optimized PNG/Subsection copy 2/Section Depth Text.png' --out '/Volumes/HD/Optimized PNG/Subsection copy 2/Section Depth Text-.PNG'
/Volumes/HD/Optimized PNG/Subsection copy 2/Section Depth Text.png
Error: Cannot do --setProperty hasAlpha on file
/Volumes/HD/Optimized PNG/Subsection copy 2/Section Depth Text-.PNG
mis-bhayward61p-swk:~ zav$
Hope this gets you a little farther.
I have a large Tiff image that I want to chop into 512x512 tiles and write to disk.
In the past I've used ImageMagick like so:
convert -crop 512x512 +repage image_in.tif image_out_%d.tif
But recently this hasn't been working, processes running out of memory, etc.
Is there a similar command in VIPS? I know there's a CLI but I can't find an example or useful explanation in the documentation, and I'm still trying to figure out the nip2 GUI thing. Any help appreciated. :)
libvips has a operator which can do this for you very quickly. Try:
$ vips dzsave wtc.tif outdir --depth one --tile-size 512 --overlap 0 --suffix .tif
That's the DeepZoom writer making a depth 1 pyramid of tif tiles. Look in outdir_files/0 for the output tiles. There's a chapter in the docs talking about how to use dzsave.
It's a lot quicker than IM for me:
$ time convert -crop 512x512 +repage huge.tif x/image_out_%d.tif
real 0m5.623s
user 0m2.060s
sys 0m2.148s
$ time vips dzsave huge.tif x --depth one --tile-size 512 --overlap 0 --suffix .tif
real 0m1.643s
user 0m1.668s
sys 0m1.000s
Where huge.tif is a 10,000 by 10,000 pixel uncompressed RGB image. Plus it'll process any size image in only a small amount of memory.
I am running into the same issue. It seems that VIPS does not have a built-in command like the one from imagemagick above, but you can do this with some scripting (Python-code snippet):
for x in xrange(0, tiles_per_row):
xoffset = x * tile_size
for y in xrange(0, tiles_per_row):
yoffset = y * tile_size
filename = "%d_%d_%d.png" % (zoom, x, y)
command = "vips im_extract_area %s %s %d %d %d %d" % (base_image_name, filename, xoffset, yoffset, tile_size, tile_size)
os.system(command)
However you won't get the same speed as with imagemagick cropping...