Compress pictures to the right size in Windows
I want to share with HabraPeople one IT quiet story that happened to me on New Year's holidays. One of my New Year's gifts was a digital photo frame from DICOM (quite a decent thing, by the way). It contains 128 MB of internal memory and a convenient interface for uploading photos - aka a flash drive. But this is not a task - in the home archive on a computer the photos are stored full-sized, but on the USB flash drive they are compressed to a small size and shown to a touched user. We must somehow deal with wastefulness - squeezing every photo with pens is a troublesome thing!
Here, I want to note that I don’t really use Windows myself - Linux, as it’s more familiar ... And there I would take an imagemagick, yes bash, and write a script ... By the way, there was a post on this topic only today . But the situation in Windows has thrown me into thought.
Of course, surely there is specific software, but the soul of a programmer requires a systematic approach) In general, I was wondering how such problems can be solved in Windows. I immediately refused to use the Windows shell (do not ask why). I decided to write progku in Java. Actually, this was done - a folder is fed to the input, all files with the desired extension are recursively searched for, whether they need to be compressed and calculated to scale them.
I bring the code (I'm new to Java, so do not scold, but the constructive criticism is very interesting): But how to run this program? Writing a user interface for such a task would again be wasteful.Having thought
Googling decided to embed this program in the context menu for devices. However, I also want to see debug printing (not so much for debugging, but rather for understanding that the process is moving). I decided to do so - cmd-file, as a wrapper for the program (still screw shell screwed). So, we make the file from the jar class, put it in C: / Program Files / imgconv / imgconv.jar, make the cmd file ConvertImages.cmd:
(Naturally, the java executable must be accessible via the PATH variable)
Now we need to add a menu item. We do this:
It turned out to be very convenient - we start it, check whether we want to resize, click ok and meditate on the process.
PS This opus is not advice, guidance or anything else in the same vein. Just a story about how, having free time, I tried to come up with a non-standard solution to a standard problem)
PPS Happy New Year to everyone!
Here, I want to note that I don’t really use Windows myself - Linux, as it’s more familiar ... And there I would take an imagemagick, yes bash, and write a script ... By the way, there was a post on this topic only today . But the situation in Windows has thrown me into thought.
Of course, surely there is specific software, but the soul of a programmer requires a systematic approach) In general, I was wondering how such problems can be solved in Windows. I immediately refused to use the Windows shell (do not ask why). I decided to write progku in Java. Actually, this was done - a folder is fed to the input, all files with the desired extension are recursively searched for, whether they need to be compressed and calculated to scale them.
I bring the code (I'm new to Java, so do not scold, but the constructive criticism is very interesting): But how to run this program? Writing a user interface for such a task would again be wasteful.
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import javax.swing.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.LinkedList;
public class ImageConverter {
static int MAX_WIDTH = 480;
static int MAX_HEIGHT = 360;
public static void main(String[] args) {
String indir = "";
if(args.length > 0){
indir = args[0];
}else{
System.out.println("Usage: imageconv path [maxwidth] [maxheight]");
return;
}
if(args.length > 2){
MAX_WIDTH = Integer.parseInt(args[1]);
MAX_HEIGHT = Integer.parseInt(args[2]);
}
System.out.println("Input directory: " + indir);
LinkedList files = getTree(new File(indir));
if(files.size() == 0){
JOptionPane.showMessageDialog(null, "Nothing to process",
"Image Convert Error",JOptionPane.ERROR_MESSAGE);
return;
}
int startSize = 0, endSize = 0;
int res = JOptionPane.showConfirmDialog(null, "Will process " + files.size() + " files on drive " + indir,
"Image Convert",JOptionPane.OK_CANCEL_OPTION);
if(res == JOptionPane.CANCEL_OPTION) return;
for(File original: files){
startSize += original.length();
System.out.print("Will process " + original.getName() + "...");
try{
if(resize(original, original)){
System.out.println("Done!");
}else{
System.out.println("No conversion.");
}
}catch(Exception e){
System.out.println(" Error: " + e.getMessage());
}
}
for(File result: files){
endSize += result.length();
}
System.out.println("Result is: start size " + startSize + ", end size is "
+ endSize);
System.out.println("Comperession is " + (100.0*(startSize - endSize) / startSize) + "%.");
return;
}
public static LinkedList getTree(File dir){
LinkedList result = new LinkedList();
if(dir.isFile()){
String fname = dir.getName();
String extension = fname;
if(fname.length()>3)
extension = fname.substring(fname.length() - 3).toLowerCase();
if("jpg".equals(extension)){
result.add(dir);
}
return result;
}
File[] children = dir.listFiles();
if(children == null) return result;
for(File s: children){
result.addAll(getTree(s));
}
return result;
}
public static boolean resize(File originalFile, File resizedFile) throws IOException {
ImageIcon ii = new ImageIcon(originalFile.getCanonicalPath());
Image i = ii.getImage();
Image resizedImage = null;
int newWidth = i.getWidth(null);
int newHeight = i.getHeight(null);
double aspectW = 1.0 * newWidth / ImageConverter.MAX_WIDTH;
double aspectH = 1.0 * newHeight / ImageConverter.MAX_HEIGHT;
System.out.println("AspectW: " + aspectW + "; AspectH: " + aspectH);
if(aspectW > 1.0 || aspectH > 1.0){
if(aspectW >= aspectH){ // resize by width
newHeight = new Double(newHeight / aspectW).intValue();
newWidth = ImageConverter.MAX_WIDTH;
}else{//resize by height
newWidth = new Double(newWidth / aspectH).intValue();
newHeight = ImageConverter.MAX_HEIGHT;
}
resizedImage = i.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH);
Image temp = new ImageIcon(resizedImage).getImage();
BufferedImage bufferedImage = new BufferedImage(temp.getWidth(null), temp.getHeight(null),
BufferedImage.TYPE_INT_RGB);
Graphics g = bufferedImage.createGraphics();
g.setColor(Color.white);
g.fillRect(0, 0, temp.getWidth(null), temp.getHeight(null));
g.drawImage(temp, 0, 0, null);
g.dispose();
FileOutputStream out = new FileOutputStream(resizedFile);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bufferedImage);
param.setQuality(1.0f, true);
encoder.setJPEGEncodeParam(param);
encoder.encode(bufferedImage);
return true;
}else{///nothing to do
return false;
}
}
}
* This source code was highlighted with Source Code Highlighter.
java -jar "C:\Program Files\imgconv\imgconv.jar" %1
pause
- Open the registry in HKEY_CLASSES_ROOT \ Drive \ shell \
- Create an Image Converter section (This will be the name of the menu item)
- In it we create the command section
- Set the default value in it C: \ Program Files \ imgconv \ ConvertImages.cmd% 1
- Check
It turned out to be very convenient - we start it, check whether we want to resize, click ok and meditate on the process.
PS This opus is not advice, guidance or anything else in the same vein. Just a story about how, having free time, I tried to come up with a non-standard solution to a standard problem)
PPS Happy New Year to everyone!