Rename images using uigetfile and cell array

Greetings,
so Im using the following function to rename my images that I would like to open via the uigetfile and then try to rename them with the movefile method. This code only works when the images are in the matlab path.
function output(~)
dirData = dir('*.jpg');
fileNames = {dirData.name};
for iFile = 1:numel(fileNames)
newName = sprintf('left%03d.jpg',iFile);
movefile(fileNames{iFile},newName);
end
But now if I try to input this:
dirData = uigetfile({'*.jpg'},'MultiSelect', 'on', 'Please selecet the images');
instead of:
dirData = dir('*.jpg');
then it just gives me the error message: Struct contents reference from a non-struct array object. Error in output (line 4) fileNames = {dirData.name};

3 Comments

That's because the uigetfile function already returns the file names in a cell array. The output differs from the dir function.
I think it's sufficient to skip that line and write
fileNames=uigetfile({'*.jpg'},'MultiSelect', 'on', 'Please selecet the images');
If I try to use your suggestion, I get the following error:
Error using movefile
No matching files were found.
Error in left (line 7) movefile(fileNames{iFile},newName);
@Marcel Liphardt: you really need to provide the full path information. Read the uigetfile documentation about its second output.

Sign in to comment.

 Accepted Answer

Use the two output form of uigetfile:
[filenames, pathname] = uigetfile({'*.jpg'}, 'MultiSelect', 'on', 'Please select the images');
fullFilenames = cellfun( @(x) fullfile( pathname, x ), filenames, 'UniformOutput', false );
and then it should work as you have the full path instead of just a filename that must be on the Matlab path.

4 Comments

Thanks Adadm,
so Im still a bit new to Matlab.
Now your fullFilenames variable is unused and the two variables: filePattern and newFileName from Image Analysts example are unused.
I don't really see where I should input these?
Adam
Adam on 15 Aug 2017
Edited: Adam on 15 Aug 2017
Your last comment to your question seemed to suggest that the problem you are having now, when using uigetfile is that when you call movefile you get a 'No matching files were found' error. This is because you don't have the full path.
If you use the 'fullFilenames' from my answer in place of your 'fileNames' this should get rid of that error.
I didn't look at ImageAnalyst's answer in detail sice you said you wanted to use uigetfile, but it looks like there are just a couple of typos in the syntax. 'newFileName' should be used instead of 'newName' after it has been declared. I'm not 100% sure what his intended use for 'filePattern' was though.
Ok Adam you*r right, this works.
So my completed code looks like this:
function left(~)
[filenames, pathname] = uigetfile({'*.jpg'}, 'MultiSelect', 'on', 'Please select the images');
fullFilenames = cellfun( @(x) fullfile( pathname, x ), filenames, 'UniformOutput', false );
for iFile = 1:numel(fullFilenames)
newName = sprintf('links%03d.jpg',iFile);
movefile(fullFilenames{iFile},newName);
end
But where does the program save those images? Im calling this function from a cell_list, where my next step would be to save these renamed images in a folder I choose.
You need to use fullfile with a directory path for your destination file too in movefile. Don't just give it a filename. By default it will just save it in the current working directory which is presumably not what you want.
doc fullfile
should help. If you are creating each new filename in a loop as you appear to be then you won't need cellfun to do these as you did for the source files.

Sign in to comment.

More Answers (1)

Try this:
folder = pwd; % Or use getdir().
filePattern = fullfile(folder, '*.jpg'); % Don't use JPG images for image analysis.
dirData = dir(filePattern);
for k = 1 : length(dirData)
thisFileName = fullfile(folder, dirData(k).name);
newName = sprintf('left%03d.jpg',k);
newFileName = fullfile(folder, newName);
fprintf('Renaming %s to %s\n', dirData(k).name, newName);
movefile(thisFileName, newName);
end

2 Comments

Hey Image Analyst,
thanks for your answer.
Isn't your sloution still to take all images at once only?
Can't I use uigetfile to achieve this, cause I actually need to choose only a few images to rename in a specific directory?
You can use this code if you want the user to specify the files:
folder = pwd; % Starting folder.
filePattern = fullfile(folder, '*.jpg'); % Don't use JPG images for image analysis.
[filenames, folder] = uigetfile(filePattern, 'MultiSelect', 'on', 'Please select the images');
for k = 1 : length(filenames)
thisFileName = fullfile(folder, filenames{k});
newName = sprintf('left%03d.jpg',k);
newFileName = fullfile(folder, newName);
fprintf('Renaming %s to %s\n', filenames{k}, newName);
movefile(thisFileName, newFileName);
end

Sign in to comment.

Categories

Find more on App Building in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!