Introduction When uploading images in some cases, the size of the image files will be limited, such as uploading an Avatar. If the image file to be uploaded is too large, you need to compress the image and there are many ways to compress the image, here we will discuss how to reduce the size of an image file by changing the length and width of the image. This problem can be described as follows: Given an image file (with an unlimited format) and the file size is S, how can we scale the length and width of the image S <m, and requires the zoom length and width ratio to be consistent with the original. IdeasIf the image length is reduced by WR and the image width is reduced by HR, the pixel data of the image is equivalent to WR * hr pixels merged into one pixel. From this we can think that the size of the image file is reduced by WR * hr. Based on this idea, we can solve our problem. Assume that the length and width ratio of an image are A. In order to compress the image file size below m, the size of the image file needs to be reduced by B times. Therefore, the image length must be reduced by WR times, the image width is reduced by HR, so we can obtain a binary one-time equation: wr / hr = a (a>=1) wr * hr = b
By solving this equation, we obtain wr = squar (b*a) hr = squar (b/a)
Sample CodeBased on the above ideas, we use QT The pseudocode for interface implementation is as follows: /* * Resize image in to out which make file size is less bound * in, input image file * out, output image file * bound, file size limit */
void compressImageByResize (char *in, char* out, qint64 bound) {
int w,h; int imageWidth, imageHeight; float sizeRadio,whRadio; bool isPortrait = false;
qint64 fileSize = 0; QFile *file = new QFile (in); fileSize = file->size(); delete file;
QImage *imgInput = new QImage (in); imageWidth = imgInput->width (); imageHeight = imgInput->height(); if (imageWidth < imageHeight) isPortrait = true;
sizeRadio = ceil(fileSize/bound);
if (isPortrait) whRadio = ceil(imageHeight/imageWidth); else whRadio = ceil(imageWidth/imageHeight);
float wScale = ceil(sqrt(sizeRadio * whRadio)); float hSacle = ceil(sqrt(sizeRadio / whRadio));
if (isPortrait) { w = imageWidth / hScale; h = imageHeight / wScale; } else { w = imageWidth / wScale; h = imageHeight / hScale; }
QImage imgOutput = imgInput->scaled (w,h); imgOutput.save (out);
delete imgOutput;
}
Note: Make sure that whradio> = 1, that is When width> = height, whRadio = imageWidth/imageWidth w = imageWidth / wScale; h = imageHeight / hScale;
When height> width, whRadio = imageHeight/imageWidth w = imageWidth / hScale h = imageHeight / wScale
|