AlbumShaper 1.0a3
imageTools.cpp
Go to the documentation of this file.
1//==============================================
2// copyright : (C) 2003-2005 by Will Stokes
3//==============================================
4// This program is free software; you can redistribute it
5// and/or modify it under the terms of the GNU General
6// Public License as published by the Free Software
7// Foundation; either version 2 of the License, or
8// (at your option) any later version.
9//==============================================
10
11//Systemwide includes
12#include <fstream>
13#include <cstdlib>
14#include <iostream>
15#include <cmath>
16
17#include <qstring.h>
18#include <qimage.h>
19#include <qdir.h>
20#include <qfile.h>
21#include <qcolor.h>
22#include <fstream>
23#include <qpoint.h>
24#include <qpainter.h>
25
26//Projectwide includes
27#include "imageTools.h"
28#include "jpeg/jpegTools.h"
29#include "jpeg/jpegSize.h"
30#include "../../config.h"
31
32//==============================================
33bool isJpeg(const char* filename)
34{
35 int w,h;
36 return getJPEGSize( QFile::encodeName(filename), w, h );
37}
38//==============================================
39void calcScaledImageDimensions(int origWidth, int origHeight,
40 int idealWidth, int idealHeight,
41 int& width, int& height)
42{
43 //if original dimensions are within ideal new size then use
44 //original dimensions
45 if(origWidth <= idealWidth &&
46 origHeight <= idealHeight)
47 {
48 width = origWidth;
49 height = origHeight;
50 return;
51 }
52
53 //else find dimension which is way over bounds
54 float widthRatio = ((float)idealWidth) / ((float)origWidth);
55 float heightRatio = ((float)idealHeight) / ((float)origHeight);
56
57 if(widthRatio < heightRatio)
58 {
59 width = idealWidth;
60 height = (int)((((float)idealWidth) / ((float)origWidth)) * ((float)origHeight));
61 }
62 else
63 {
64 height = idealHeight;
65 width = (int)((((float)idealHeight) / ((float)origHeight)) * ((float)origWidth));
66 }
67}
68//==============================================
69void constructImages(QString imageName,
70 QImage& slideshowImage, QImage& thumbnailImage)
71{
72 //---------------------------------------------------------
73 //obtain original image width and height
74 int origWidth, origHeight;
75 getImageSize( imageName, origWidth, origHeight );
76
77 //compute dimensions of unhapped scaled thumbnail and slideshow images
78 int thumbWidth, thumbHeight;
79 calcScaledImageDimensions( origWidth, origHeight,
81 thumbWidth, thumbHeight);
82
83 int slideWidth, slideHeight;
84 calcScaledImageDimensions( origWidth, origHeight,
86 slideWidth, slideHeight);
87 //---------------------------------------------------------
88 //create slide show image
89
90 //first scale full image to unpadded dimensions
91 QImage temp;
92 scaleImage( imageName, temp, slideWidth, slideHeight );
93 slideWidth = temp.width();
94 slideHeight = temp.height();
95
96 //create slideshow image and fill with white
97 slideshowImage.create( SLIDESHOW_WIDTH, SLIDESHOW_HEIGHT, 32 );
98 slideshowImage.fill( QColor(Qt::white).rgb() );
99
100 //paint unpadded scaled image
101 int xDiff = SLIDESHOW_WIDTH - slideWidth;
102 int yDiff = SLIDESHOW_HEIGHT - slideHeight;
103 bitBlt( &slideshowImage, xDiff/2, yDiff/2,
104 &temp, 0, 0, slideWidth, slideHeight );
105
106 //---------------------------------------------------------
107 //create thumnail image
108 scaleImage( imageName, thumbnailImage, thumbWidth, thumbHeight );
109 //---------------------------------------------------------
110}
111//==============================================
112bool transformImage( QString fileIn, QString fileOut, TRANSFORM_CODE transformation )
113{
114 //if file is jpeg use faster method
115 if( isJpeg(fileIn) )
116 return transformJPEG( fileIn, fileOut, transformation );
117
118 //load image
119 QImage origImage(fileIn);
120 QImage transformedImage;
121
122 //transform image
123 if(transformation == ROTATE_90)
124 {
125 if(!transformedImage.create( origImage.height(), origImage.width(), origImage.depth() ) )
126 return false;
127
128 int x,y;
129 for(x=0; x < origImage.height(); x++)
130 {
131 for(y=0; y < origImage.width(); y++)
132 transformedImage.setPixel(origImage.height() - 1 - x, y, origImage.pixel(y, x) );
133 }
134 }
135 else if(transformation == ROTATE_270)
136 {
137 if(!transformedImage.create( origImage.height(), origImage.width(), origImage.depth() ) )
138 return false;
139
140 int x,y;
141 for(x=0; x < origImage.height(); x++)
142 {
143 for(y=0; y < origImage.width(); y++)
144 transformedImage.setPixel(x, origImage.width() - 1 - y, origImage.pixel(y, x) );
145 }
146 }
147 else if(transformation == FLIP_H)
148 { transformedImage = origImage.mirror(false,true); }
149 else
150 { transformedImage = origImage.mirror(true,false); }
151
152 //save out transformed image
153 transformedImage.save( fileOut, "JPEG", 95 );
154 return true;
155}
156//==============================================
157bool scaleImage( QString fileIn, QString fileOut,
158 int newWidth, int newHeight)
159{
160 //scale image
161 QImage scaledImage;
162 if( scaleImage(fileIn, scaledImage, newWidth, newHeight ) )
163 {
164 scaledImage.save( fileOut, "JPEG", 95 );
165 return true;
166 }
167 else
168 return false;
169}
170//==============================================
171bool scaleImage(QString fileIn, QImage& scaledImage, int targetWidth, int targetHeight)
172{
173 //if file is jpeg use faster method
174 QString extension = QFileInfo(fileIn).extension(false).lower();
175 if( extension.compare("jpeg") == 0 ||
176 extension.compare("jpg") == 0 )
177 return scaleJPEG( QFile::encodeName(fileIn), scaledImage, targetWidth, targetHeight );
178
179 //use slow smooth-scale method for scaling image.
180 //clamp scaling to <= 2x
181 QImage orig(fileIn);
182 if(QMIN( ((float)targetWidth)/orig.width(), ((float)targetHeight)/orig.height() ) > 2)
183 {
184 targetWidth = 2*orig.width();
185 targetHeight = 2*orig.height();
186 }
187
188 scaledImage = orig.smoothScale( targetWidth, targetHeight, Qt::KeepAspectRatio );
189 return true;
190}
191//==============================================
192bool getImageSize( const char* filename,QSize& size )
193{
194 int w,h;
195 bool result = getImageSize( filename, w, h );
196 size.setWidth( w );
197 size.setHeight( h );
198 return result;
199}
200//==============================================
201bool getImageSize( const char* filename, int& width, int& height )
202{
203 //if file is jpeg use faster method
204 QString extension = QFileInfo(filename).extension(false).lower();
205 if( extension.compare("jpeg") == 0 ||
206 extension.compare("jpg") == 0 )
207 return getJPEGSize( QFile::encodeName(filename),
208 width, height );
209
210 //load entire image to qimage object in order to determine size
211 QImage image(filename);
212 width = image.width();
213 height = image.height();
214 return true;
215}
216//==============================================
217double RGBtoL(QRgb* rgb)
218{
219 double r = ((double)qRed(*rgb) )/255.0;
220 double g = ((double)qGreen(*rgb) )/255.0;
221 double b = ((double)qBlue(*rgb) )/255.0;
222
223 double h,s,v;
224 RGBtoHSV(r,g,b,&h,&s,&v);
225 return 255.0*v;
226}
227//==============================================
228//RGB to HSV and HSB to RGB algorithms based
229//on by A. R. Smith in 1978, found at
230//http://www.cs.rit.edu/~ncs/color/t_convert.html
231void RGBtoHSV( double r, double g, double b,
232 double *h, double *s, double *v )
233{
234 double min, max, delta;
235
236 min = QMIN(QMIN( r, g), b );
237 max = QMAX(QMAX( r, g), b );
238 *v = max; // v
239
240 delta = max - min;
241
242 if( max != 0 )
243 *s = delta / max; // s
244 else {
245 // r = g = b = 0 // s = 0, v is undefined
246 *s = 0;
247 *h = -1;
248 return;
249 }
250
251 if( r == max )
252 *h = ( g - b ) / delta; // between yellow & magenta
253 else if( g == max )
254 *h = 2 + ( b - r ) / delta; // between cyan & yellow
255 else
256 *h = 4 + ( r - g ) / delta; // between magenta & cyan
257
258 *h *= 60; // degrees
259 if( *h < 0 )
260 *h += 360;
261
262}
263//==============================================
264void HSVtoRGB( double *r, double *g, double *b,
265 double h, double s, double v )
266{
267 int i;
268 double f, p, q, t;
269
270 if( s == 0 ) {
271 // achromatic (grey)
272 *r = *g = *b = v;
273 return;
274 }
275
276 h /= 60; // sector 0 to 5
277 i = (int)floor( h );
278 f = h - i; // factorial part of h
279 p = v * ( 1 - s );
280 q = v * ( 1 - s * f );
281 t = v * ( 1 - s * ( 1 - f ) );
282
283 switch( i ) {
284 case 0:
285 *r = v;
286 *g = t;
287 *b = p;
288 break;
289 case 1:
290 *r = q;
291 *g = v;
292 *b = p;
293 break;
294 case 2:
295 *r = p;
296 *g = v;
297 *b = t;
298 break;
299 case 3:
300 *r = p;
301 *g = q;
302 *b = v;
303 break;
304 case 4:
305 *r = t;
306 *g = p;
307 *b = v;
308 break;
309 default: // case 5:
310 *r = v;
311 *g = p;
312 *b = q;
313 break;
314 }
315}
316//==============================================
float q
Definition blur.cpp:78
int width
Definition blur.cpp:79
int height
Definition blur.cpp:79
#define SLIDESHOW_WIDTH
Definition config.h:26
#define THUMBNAIL_HEIGHT
Definition config.h:25
#define SLIDESHOW_HEIGHT
Definition config.h:27
#define THUMBNAIL_WIDTH
Definition config.h:24
bool scaleImage(QString fileIn, QString fileOut, int newWidth, int newHeight)
Scale image and save copy to disk.
void constructImages(QString imageName, QImage &slideshowImage, QImage &thumbnailImage)
Constructs slideshow and thumbnail images for a full sized image.
bool getImageSize(const char *filename, QSize &size)
Get image dimensions.
void RGBtoHSV(double r, double g, double b, double *h, double *s, double *v)
Convert a RGB color triplet to HSV.
double RGBtoL(QRgb *rgb)
find luminance of a rgb color triplet
void HSVtoRGB(double *r, double *g, double *b, double h, double s, double v)
Convert a HSV color triplet to RGB.
void calcScaledImageDimensions(int origWidth, int origHeight, int idealWidth, int idealHeight, int &width, int &height)
Computes scale of image dimensions while respecting aspect ratio, equivalent to a QImage::scaleMin wi...
bool transformImage(QString fileIn, QString fileOut, TRANSFORM_CODE transformation)
Apply image transformation on image
bool isJpeg(const char *filename)
Checks to see if an image is a valid jpg by seeing if the image dimensions can be read.
TRANSFORM_CODE
Definition imageTools.h:25
@ ROTATE_270
Definition imageTools.h:27
@ ROTATE_90
Definition imageTools.h:26
@ FLIP_H
Definition imageTools.h:28
long b
bool getJPEGSize(const char *filename, int &width, int &height)
Definition jpegSize.cpp:65
bool scaleJPEG(QString fileIn, QImage &scaledImage, int targetWidth, int targetHeight)
Definition jpegTools.cpp:54
bool transformJPEG(QString fileIn, QString fileOut, TRANSFORM_CODE transformation)