In my rails app, i let the user upload images to use as thumbnails for resources they've made. I do all the image processing with imagemagick's convert command: i convert to jpg, letterbox it to 800x600px and then make some smaller thumbnail versions of that.
This is all working fine. The problem is that some images that have come off my iPhone, for example, have the wrong orientation. My desktop seems to variously deal with this: when i see the tiny thumbnail for the image in the file chooser dialog, it's got the wrong orientation, but if I open it in the image viewing tool, it's got the correct orientation.
Presumably there's some header or metadata or something in the image file which tells the app that it needs to rotate the file? I think that I need to read this in before I do any other processing of the image, so that I can rotate the image (if necessary) before doing all the other stuff.
Can anyone tell me how I can do this, in bash on an Ubuntu server?
thanks, Max
EDIT: a bit of googling suggests that this is to to with EXIF headers...
It's true that you will have to look for orientation value reading Exif metadata of Image. Using imagemagick you can get this value by
identify -format '%[exif:orientation]' <Path to Image>
//or by using
identify -format '%[orientation]' <Path to Image>
Exif Orientation values range from 1 to 8 and maps to orientation as below:
1 = Horizontal (normal)
2 = Mirror horizontal
3 = Rotate 180
4 = Mirror vertical
5 = Mirror horizontal and rotate 270 CW
6 = Rotate 90 CW
7 = Mirror horizontal and rotate 90 CW
8 = Rotate 270 CW
Thus, image would require orientation correction if this metadata tag returns with a non 1 value. If this tag returns with no value it can be assumed to be having normal orientation.
To correct orientation to normal you can use following command
convert -auto-orient <inputImagePath> <outputImagePath>
Try
identify -format "%f %[EXIF:Orientation]" <imagename>
This gives a number from 1 to 8. These numbers are documented here
Related
I am trying to open a 1920x1080 YCbCr raw image file in Matlab, however I am having difficulties getting the following code below to work:
fid = fopen(filePath);
image = fread(fid, 1920*1080, 'uint8=>uint8');
fclose(fid);
image = reshape(image, 1080, 1920);
However, when I go to show the image, it does not look as expected.
The actual image should be colour, however I get a strange black and white image, not resembling the expected output at all.
I have also tried loading it into a 3D array, with each dimension representing one of the Y, Cb and Cr channels, however this also produced a similar output as described before.
Any help would be appreciated.
Ignore this bit and look below at the EDIT:
I don't understand why you are using fread? Why not use imread,
which is mean't for reading images? Using this infamous original
image, as a base for my test script, I could display a YCbCr
image, as shown in the little script below.
original = imread("lenna.jpg");
% figure, imshow(original); % if you want to see how the original image looks
YCbCr_version = rgb2ycbcr(original);
% figure, imshow(YCbCr_version); % if you want to see how the YCbCr image looks
imwrite(YCbCr_version, "out.jpg");
YCbCr_fromFile = imread("out.jpg");
figure, imshow(YCbCr_fromFile);
EDIT:
IF however you have a binary version of the file and can only read it using using fread,
then the following script should work,
clc;
clear;
close all;
original = imread("lenna.jpg");
% figure, imshow(original); % if you want to see how the original image looks
YCbCr_version = rgb2ycbcr(original);
% figure, imshow(YCbCr_version); % if you want to see how the YCbCr image looks
fileID = fopen('out.bin','w');
fwrite(fileID, YCbCr_version, 'uint8');
fclose(fileID);
fileID = fopen('out.bin','r');
fromFile = fread(fileID, 512*600*3, 'uint8=>uint8');
fclose(fileID);
image = reshape(fromFile, 512, 600, 3);
imagesc(image)
The point is, in the read operation, you have to give the 3 channels in the multiplier also, as color images have this 3rd dimension, i.e. 512*600*3. If you only give 512*600, as you were doing, you would have no color info. Also the reshape function would need to be changed to take into account the 3rd dimension. Hence, reshape(fromFile, 512,600, 3).
YCbCr version loaded from the file
As you said "Any help would be appreciated", I thought I would mention you can simply convert a raw YCbCr file to PNG, TIFF, JPEG or any other format file with ImageMagick which is installed on most Linux distros and is available for macOS and Windows.
Start a Terminal, (or Command Prompt if under Windows), and convert the YCbCr image.raw to PNG with:
magick -size 1920x1080 -depth 8 YCbCr:image.raw result.png
Or, say a CCIR 601 YUV file to NetPBM PPM format:
magick -size 800x600 -depth 8 YUV:image.raw result.ppm
We're trying to achieve building a custom social sharing image from our app. The backend is built using Ruby/Sinatra and we already use MiniMagick+AWS-SDK to upload user images.
What we want to do is take the user's image and add a stock overlay (it contains a white circle as the placeholder for the variable user image) on top of the user image. I tried using MiniMagick's built-in composite method using Over as the operator, but the problem with Overis, if the overlay is larger than the source, it automatically adjusts according to the source's size. Our overlay is larger and we want to retain the overlay such that the resulting image has the complete overlay with the part of the user image that fits the placeholder white circle visible underneath.
I tried How to use Imagick to merge and mask images? but it doesn't solve my problem.
Basically, say this is the overlay.
And take this sample user image as example:
https://s-media-cache-ak0.pinimg.com/564x/71/08/b5/7108b5a89ce3d6cc0341f876681f8546.jpg
I would like the resulting image to be the complete overlay with the user image visible behind one of those while circles.
Update
As per Mark'sanswer, I wrote the following Ruby code to achieve the result:
avatar = avatar.resize "200x200"
result = mask.composite(avatar) do |c|
c.compose "DstOver"
c.geometry "+100+120" #this could be different depending on your mask's dimensions
end
You can test the result by executing result.write "result.jpg"
Not too sure what you are doing as your mask is an opaque JPEG? However, I think you mean to use a transparent PNG for the mask with a hole in it, in which case you could do this:
convert mask.png \( avatar.jpg -resize 200x200 \) -geometry +360+150 -compose dst-over -composite result.jpg
I would like to be able to use the cpselect matlab tool (or a similar one) with the capability of showing both images (moving image and reference image) in RGB (I only managed to see moving image in RGB and reference image in grayscale).
Could someone point me to an alternative for this tool that would support this or anyway to be able to display both image in rgb in cpselect?
Thanks in advance.
Not sure what you're talking about, and I'm quite confused about your statement. cpselect is image independent. You can show both of them as colour or grayscale or one or the other. The example you're probably looking at is the one that comes with MATLAB: http://www.mathworks.com/help/images/ref/cpselect.html . One image is grayscale, while the other has a pinkish hue.
Here's an example showing both the source and target image as being in colour. I used onion.png that is a colour image that is part of the MATLAB system path:
im = imread('onion.png');
im_rotate = imrotate(im, 35);
cpselect(im, im_rotate);
We get:
I ve an image which has 6 images within it..I ve the task of cropping the 6 images out of this image..
Currently I follow this procedure..
1. Save copy of original image
2. Crop the image to get first image using any tool(Picasa)
3. Save the cropped image as image 1
4. Open the original to crop for image 2
5. Repeat this 6 times
Is there a way in which I can extract out all the 6 images in one go? Multi-cropping?
Yes, it's possible. You need to get familiarized with the ROI (Region of Interest) concept.
This C example shows how to set a ROI in an image. Basically it sets a ROI in a frame from the camera, creates a new image from it, does some processing (invert colors) in the image and then copies the image back to the original frame for display.
This Python example also shows how to work with ROIs.
From the OP description, it sounds like the OP just wants to automated way to crop an image into 6 pieces.
Google for "irfanview batch crop" or "ImageMagick batch crop"
If a more complex cropping logic/procedure is needed, then gfx library of the OP's language of choice should have a cropping function that they can code.
OpenCV would be an overkill for this task.
if OP insist on using OpenCV, then set the ROI
Mat image = imread("src_image_path");
Rect roi = Rect(x, y, w, h);
Mat image_roi = image(roi);
imwrite("dest_image_path", image_roi);
In MATLAB, how do you write a matrix into an image of EPS format?
It seems imwrite does not support EPS.
Convert is not working on the Linux server I am using:
$ convert exploss_stumps.jpg exploss_stumps.eps
convert: missing an image filename `exploss_stumps.eps' # convert.c/ConvertImageCommand/2838
Why?
I tried gnovice's idea under terminal mode:
figH = figure('visible','off') ;
imshow(img,'border','tight',... %# Display in a figure window without
'InitialMagnification',100); %# a border at full magnification
print(strcat(filepath,'/', dataset,'_feature_',num2str(j), '.eps'),'-depsc2');
close(figH) ;
However I got:
??? Error using ==> imshow at 191
IMSHOW requires Java to run.
Error in ==> study_weaker at 122
imshow(img,'border','tight',... %# Display in a figure window without
191 error(eid,'%s requires Java to run.',upper(mfilename));
How can I fix it?
One possible solution is to plot your image using IMSHOW, then print the entire figure as a .eps using PRINT:
img = imread('peppers.png'); %# A sample image
imshow(img,'Border','tight',... %# Display in a figure window without
'InitialMagnification',100); %# a border at full magnification
print('new_image.eps','-deps'); %# Print the figure as a B&W eps
One drawback to this solution is that if the image is too big to fit on the screen, IMSHOW will shrink it to fit, which will reduce the on-screen resolution of the image. However, you can adjust the final resolution of the saved image using the -r<number> option for the PRINT function. For example, you can print your figure as an Encapsulated Level 2 Color PostScript with a resolution of 300 dpi by doing the following:
print('new_image.eps','-depsc2','-r300');
EDIT: If you are unable to use IMSHOW (either because you don't have the Image Processing Toolbox or because you are using a MATLAB mode that doesn't allow it), here is an alternative way to create and print the figure:
img = imread('peppers.png'); %# A sample image
imagesc(img); %# Plot the image
set(gca,'Units','normalized',... %# Set some axes properties
'Position',[0 0 1 1],...
'Visible','off');
set(gcf,'Units','pixels',... %# Set some figure properties
'Position',[100 100 size(img,2) size(img,1)]);
print(gcf,'new_image.eps','-depsc2','-r300'); %# Print the figure
You can also take a look at this documentation to see how printing works without a display.
It should work using imwrite. You would have to add a colormap for it to work though.
However, ckecking the help pages I see that it is NOT possible to use imwrite to write an EPS file.
Following code may help you to convert png file to eps.
fileName = 'FarmerStats'; % your FILE NAME as string
A = imread(fileName,'png');
set(gcf,'visible','off') %suppress figure
image(A);
axis image % resolution based on image
axis off % avoid printing axis
set(gca,'LooseInset',get(gca,'TightInset')); % removing extra white space in figure
saveas(gcf,fileName,'epsc'); % save as COLOR eps file