summaryrefslogtreecommitdiff
path: root/libopie2
authoralwin <alwin>2005-03-24 21:13:40 (UTC)
committer alwin <alwin>2005-03-24 21:13:40 (UTC)
commitb6fc9840f4fe9bad392167c49dbcfa2acda9ed21 (patch) (unidiff)
tree1d7d1225a9c440f5d0608d8901dfd151db8a6f1c /libopie2
parent1e6c3181dcc7ec4edbe99db0d886ce7a9c483056 (diff)
downloadopie-b6fc9840f4fe9bad392167c49dbcfa2acda9ed21.zip
opie-b6fc9840f4fe9bad392167c49dbcfa2acda9ed21.tar.gz
opie-b6fc9840f4fe9bad392167c49dbcfa2acda9ed21.tar.bz2
last bugfixes on opie-eye an imagescrollview. Seems that now all is working
as it should.
Diffstat (limited to 'libopie2') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiemm/oimagescrollview.cpp5
1 files changed, 4 insertions, 1 deletions
diff --git a/libopie2/opiemm/oimagescrollview.cpp b/libopie2/opiemm/oimagescrollview.cpp
index 10da823..76f50e1 100644
--- a/libopie2/opiemm/oimagescrollview.cpp
+++ b/libopie2/opiemm/oimagescrollview.cpp
@@ -112,337 +112,340 @@ void OImageScrollView::loadJpeg(bool interncall)
112 real_load = true; 112 real_load = true;
113 } 113 }
114 } else { 114 } else {
115 if (ImageScaledLoaded()||!interncall) { 115 if (ImageScaledLoaded()||!interncall) {
116 real_load = true; 116 real_load = true;
117 } 117 }
118 setImageScaledLoaded(false); 118 setImageScaledLoaded(false);
119 } 119 }
120 if (real_load) { 120 if (real_load) {
121 _original_data = iio.read() ? iio.image() : QImage(); 121 _original_data = iio.read() ? iio.image() : QImage();
122 } 122 }
123} 123}
124 124
125void OImageScrollView::setImage( const QString& path ) { 125void OImageScrollView::setImage( const QString& path ) {
126 if (m_lastName == path) return; 126 if (m_lastName == path) return;
127 m_lastName = path; 127 m_lastName = path;
128 _newImage = true; 128 _newImage = true;
129 _original_data = QImage(); 129 _original_data = QImage();
130 QString itype = QImage::imageFormat(m_lastName); 130 QString itype = QImage::imageFormat(m_lastName);
131 if (itype == "JPEG") { 131 if (itype == "JPEG") {
132 setImageIsJpeg(true); 132 setImageIsJpeg(true);
133 loadJpeg(); 133 loadJpeg();
134 } else { 134 } else {
135 setImageIsJpeg(false); 135 setImageIsJpeg(false);
136 _original_data.load(path); 136 _original_data.load(path);
137 _original_data.convertDepth(QPixmap::defaultDepth()); 137 _original_data.convertDepth(QPixmap::defaultDepth());
138 _original_data.setAlphaBuffer(false); 138 _original_data.setAlphaBuffer(false);
139 } 139 }
140 _image_data = QImage(); 140 _image_data = QImage();
141 if (FirstResizeDone()) { 141 if (FirstResizeDone()) {
142 generateImage(); 142 generateImage();
143 if (isVisible()) viewport()->repaint(true); 143 if (isVisible()) viewport()->repaint(true);
144 } 144 }
145} 145}
146 146
147/* should be called every time the QImage changed it content */ 147/* should be called every time the QImage changed it content */
148void OImageScrollView::init() 148void OImageScrollView::init()
149{ 149{
150 /* 150 /*
151 * create the zoomer 151 * create the zoomer
152 * and connect ther various signals 152 * and connect ther various signals
153 */ 153 */
154 _zoomer = new Opie::MM::OImageZoomer( this, "The Zoomer" ); 154 _zoomer = new Opie::MM::OImageZoomer( this, "The Zoomer" );
155 connect(_zoomer, SIGNAL( zoomAreaRel(int,int)), 155 connect(_zoomer, SIGNAL( zoomAreaRel(int,int)),
156 this, SLOT(scrollBy(int,int)) ); 156 this, SLOT(scrollBy(int,int)) );
157 connect(_zoomer, SIGNAL( zoomArea(int,int)), 157 connect(_zoomer, SIGNAL( zoomArea(int,int)),
158 this, SLOT(center(int,int)) ); 158 this, SLOT(center(int,int)) );
159 connect(this,SIGNAL(contentsMoving(int,int)), 159 connect(this,SIGNAL(contentsMoving(int,int)),
160 _zoomer, (SLOT(setVisiblePoint(int,int))) ); 160 _zoomer, (SLOT(setVisiblePoint(int,int))) );
161 connect(this,SIGNAL(imageSizeChanged(const QSize&)), 161 connect(this,SIGNAL(imageSizeChanged(const QSize&)),
162 _zoomer, SLOT(setImageSize(const QSize&)) ); 162 _zoomer, SLOT(setImageSize(const QSize&)) );
163 connect(this,SIGNAL(viewportSizeChanged(const QSize&)), 163 connect(this,SIGNAL(viewportSizeChanged(const QSize&)),
164 _zoomer, SLOT(setViewPortSize(const QSize&)) ); 164 _zoomer, SLOT(setViewPortSize(const QSize&)) );
165 165
166 setBackgroundColor(white); 166 setBackgroundColor(white);
167 setFocusPolicy(QWidget::StrongFocus); 167 setFocusPolicy(QWidget::StrongFocus);
168 setImageScaledLoaded(false); 168 setImageScaledLoaded(false);
169 setImageIsJpeg(false); 169 setImageIsJpeg(false);
170 if (FirstResizeDone()) { 170 if (FirstResizeDone()) {
171 m_last_rot = Rotate0; 171 m_last_rot = Rotate0;
172 generateImage(); 172 generateImage();
173 } else if (_original_data.size().isValid()) { 173 } else if (_original_data.size().isValid()) {
174 if (image_fit_into(_original_data.size()) || !ShowZoomer()) _zoomer->hide(); 174 if (image_fit_into(_original_data.size()) || !ShowZoomer()) _zoomer->hide();
175 resizeContents(_original_data.width(),_original_data.height()); 175 resizeContents(_original_data.width(),_original_data.height());
176 } 176 }
177 _intensity = 0; 177 _intensity = 0;
178} 178}
179 179
180void OImageScrollView::setAutoRotate(bool how) 180void OImageScrollView::setAutoRotate(bool how)
181{ 181{
182 /* to avoid double repaints */ 182 /* to avoid double repaints */
183 if (AutoRotate() != how) { 183 if (AutoRotate() != how) {
184 m_states.setBit(AUTO_ROTATE,how); 184 m_states.setBit(AUTO_ROTATE,how);
185 _image_data = QImage(); 185 _image_data = QImage();
186 generateImage(); 186 generateImage();
187 } 187 }
188} 188}
189 189
190bool OImageScrollView::AutoRotate()const 190bool OImageScrollView::AutoRotate()const
191{ 191{
192 return m_states.testBit(AUTO_ROTATE); 192 return m_states.testBit(AUTO_ROTATE);
193} 193}
194 194
195void OImageScrollView::setAutoScaleRotate(bool scale, bool rotate) 195void OImageScrollView::setAutoScaleRotate(bool scale, bool rotate)
196{ 196{
197 m_states.setBit(AUTO_ROTATE,rotate); 197 m_states.setBit(AUTO_ROTATE,rotate);
198 setAutoScale(scale); 198 setAutoScale(scale);
199} 199}
200 200
201void OImageScrollView::setAutoScale(bool how) 201void OImageScrollView::setAutoScale(bool how)
202{ 202{
203 m_states.setBit(AUTO_SCALE,how); 203 m_states.setBit(AUTO_SCALE,how);
204 _image_data = QImage(); 204 _image_data = QImage();
205 if (ImageIsJpeg() && how == false && ImageScaledLoaded()==true) { 205 if (ImageIsJpeg() && how == false && ImageScaledLoaded()==true) {
206 loadJpeg(true); 206 loadJpeg(true);
207 } 207 }
208 _newImage = true;
208 generateImage(); 209 generateImage();
209} 210}
210 211
211bool OImageScrollView::AutoScale()const 212bool OImageScrollView::AutoScale()const
212{ 213{
213 return m_states.testBit(AUTO_SCALE); 214 return m_states.testBit(AUTO_SCALE);
214} 215}
215 216
216OImageScrollView::~OImageScrollView() 217OImageScrollView::~OImageScrollView()
217{ 218{
218} 219}
219 220
220void OImageScrollView::rescaleImage(int w, int h) 221void OImageScrollView::rescaleImage(int w, int h)
221{ 222{
222 if (_image_data.width()==w && _image_data.height()==h) { 223 if (_image_data.width()==w && _image_data.height()==h) {
223 return; 224 return;
224 } 225 }
225 double hs = (double)h / (double)_image_data.height() ; 226 double hs = (double)h / (double)_image_data.height() ;
226 double ws = (double)w / (double)_image_data.width() ; 227 double ws = (double)w / (double)_image_data.width() ;
227 double scaleFactor = (hs > ws) ? ws : hs; 228 double scaleFactor = (hs > ws) ? ws : hs;
228 int smoothW = (int)(scaleFactor * _image_data.width()); 229 int smoothW = (int)(scaleFactor * _image_data.width());
229 int smoothH = (int)(scaleFactor * _image_data.height()); 230 int smoothH = (int)(scaleFactor * _image_data.height());
230 _image_data = _image_data.smoothScale(smoothW,smoothH); 231 _image_data = _image_data.smoothScale(smoothW,smoothH);
231} 232}
232 233
233void OImageScrollView::rotate_into_data(Rotation r) 234void OImageScrollView::rotate_into_data(Rotation r)
234{ 235{
235 /* realy - we must do this that way, 'cause when acting direct on _image_data the app will 236 /* realy - we must do this that way, 'cause when acting direct on _image_data the app will
236 segfault :( */ 237 segfault :( */
237 QImage dest; 238 QImage dest;
238 int x, y; 239 int x, y;
239 if ( _original_data.depth() > 8 ) 240 if ( _original_data.depth() > 8 )
240 { 241 {
241 unsigned int *srcData, *destData; 242 unsigned int *srcData, *destData;
242 switch ( r ) 243 switch ( r )
243 { 244 {
244 case Rotate90: 245 case Rotate90:
245 dest.create(_original_data.height(), _original_data.width(), _original_data.depth()); 246 dest.create(_original_data.height(), _original_data.width(), _original_data.depth());
246 for ( y=0; y < _original_data.height(); ++y ) 247 for ( y=0; y < _original_data.height(); ++y )
247 { 248 {
248 srcData = (unsigned int *)_original_data.scanLine(y); 249 srcData = (unsigned int *)_original_data.scanLine(y);
249 for ( x=0; x < _original_data.width(); ++x ) 250 for ( x=0; x < _original_data.width(); ++x )
250 { 251 {
251 destData = (unsigned int *)dest.scanLine(x); 252 destData = (unsigned int *)dest.scanLine(x);
252 destData[_original_data.height()-y-1] = srcData[x]; 253 destData[_original_data.height()-y-1] = srcData[x];
253 } 254 }
254 } 255 }
255 break; 256 break;
256 case Rotate180: 257 case Rotate180:
257 dest.create(_original_data.width(), _original_data.height(), _original_data.depth()); 258 dest.create(_original_data.width(), _original_data.height(), _original_data.depth());
258 for ( y=0; y < _original_data.height(); ++y ) 259 for ( y=0; y < _original_data.height(); ++y )
259 { 260 {
260 srcData = (unsigned int *)_original_data.scanLine(y); 261 srcData = (unsigned int *)_original_data.scanLine(y);
261 destData = (unsigned int *)dest.scanLine(_original_data.height()-y-1); 262 destData = (unsigned int *)dest.scanLine(_original_data.height()-y-1);
262 for ( x=0; x < _original_data.width(); ++x ) 263 for ( x=0; x < _original_data.width(); ++x )
263 destData[_original_data.width()-x-1] = srcData[x]; 264 destData[_original_data.width()-x-1] = srcData[x];
264 } 265 }
265 break; 266 break;
266 case Rotate270: 267 case Rotate270:
267 dest.create(_original_data.height(), _original_data.width(), _original_data.depth()); 268 dest.create(_original_data.height(), _original_data.width(), _original_data.depth());
268 for ( y=0; y < _original_data.height(); ++y ) 269 for ( y=0; y < _original_data.height(); ++y )
269 { 270 {
270 srcData = (unsigned int *)_original_data.scanLine(y); 271 srcData = (unsigned int *)_original_data.scanLine(y);
271 for ( x=0; x < _original_data.width(); ++x ) 272 for ( x=0; x < _original_data.width(); ++x )
272 { 273 {
273 destData = (unsigned int *)dest.scanLine(_original_data.width()-x-1); 274 destData = (unsigned int *)dest.scanLine(_original_data.width()-x-1);
274 destData[y] = srcData[x]; 275 destData[y] = srcData[x];
275 } 276 }
276 } 277 }
277 break; 278 break;
278 default: 279 default:
279 dest = _original_data; 280 dest = _original_data;
280 break; 281 break;
281 } 282 }
282 } 283 }
283 else 284 else
284 { 285 {
285 unsigned char *srcData, *destData; 286 unsigned char *srcData, *destData;
286 unsigned int *srcTable, *destTable; 287 unsigned int *srcTable, *destTable;
287 switch ( r ) 288 switch ( r )
288 { 289 {
289 case Rotate90: 290 case Rotate90:
290 dest.create(_original_data.height(), _original_data.width(), _original_data.depth()); 291 dest.create(_original_data.height(), _original_data.width(), _original_data.depth());
291 dest.setNumColors(_original_data.numColors()); 292 dest.setNumColors(_original_data.numColors());
292 srcTable = (unsigned int *)_original_data.colorTable(); 293 srcTable = (unsigned int *)_original_data.colorTable();
293 destTable = (unsigned int *)dest.colorTable(); 294 destTable = (unsigned int *)dest.colorTable();
294 for ( x=0; x < _original_data.numColors(); ++x ) 295 for ( x=0; x < _original_data.numColors(); ++x )
295 destTable[x] = srcTable[x]; 296 destTable[x] = srcTable[x];
296 for ( y=0; y < _original_data.height(); ++y ) 297 for ( y=0; y < _original_data.height(); ++y )
297 { 298 {
298 srcData = (unsigned char *)_original_data.scanLine(y); 299 srcData = (unsigned char *)_original_data.scanLine(y);
299 for ( x=0; x < _original_data.width(); ++x ) 300 for ( x=0; x < _original_data.width(); ++x )
300 { 301 {
301 destData = (unsigned char *)dest.scanLine(x); 302 destData = (unsigned char *)dest.scanLine(x);
302 destData[_original_data.height()-y-1] = srcData[x]; 303 destData[_original_data.height()-y-1] = srcData[x];
303 } 304 }
304 } 305 }
305 break; 306 break;
306 case Rotate180: 307 case Rotate180:
307 dest.create(_original_data.width(), _original_data.height(), _original_data.depth()); 308 dest.create(_original_data.width(), _original_data.height(), _original_data.depth());
308 dest.setNumColors(_original_data.numColors()); 309 dest.setNumColors(_original_data.numColors());
309 srcTable = (unsigned int *)_original_data.colorTable(); 310 srcTable = (unsigned int *)_original_data.colorTable();
310 destTable = (unsigned int *)dest.colorTable(); 311 destTable = (unsigned int *)dest.colorTable();
311 for ( x=0; x < _original_data.numColors(); ++x ) 312 for ( x=0; x < _original_data.numColors(); ++x )
312 destTable[x] = srcTable[x]; 313 destTable[x] = srcTable[x];
313 for ( y=0; y < _original_data.height(); ++y ) 314 for ( y=0; y < _original_data.height(); ++y )
314 { 315 {
315 srcData = (unsigned char *)_original_data.scanLine(y); 316 srcData = (unsigned char *)_original_data.scanLine(y);
316 destData = (unsigned char *)dest.scanLine(_original_data.height()-y-1); 317 destData = (unsigned char *)dest.scanLine(_original_data.height()-y-1);
317 for ( x=0; x < _original_data.width(); ++x ) 318 for ( x=0; x < _original_data.width(); ++x )
318 destData[_original_data.width()-x-1] = srcData[x]; 319 destData[_original_data.width()-x-1] = srcData[x];
319 } 320 }
320 break; 321 break;
321 case Rotate270: 322 case Rotate270:
322 dest.create(_original_data.height(), _original_data.width(), _original_data.depth()); 323 dest.create(_original_data.height(), _original_data.width(), _original_data.depth());
323 dest.setNumColors(_original_data.numColors()); 324 dest.setNumColors(_original_data.numColors());
324 srcTable = (unsigned int *)_original_data.colorTable(); 325 srcTable = (unsigned int *)_original_data.colorTable();
325 destTable = (unsigned int *)dest.colorTable(); 326 destTable = (unsigned int *)dest.colorTable();
326 for ( x=0; x < _original_data.numColors(); ++x ) 327 for ( x=0; x < _original_data.numColors(); ++x )
327 destTable[x] = srcTable[x]; 328 destTable[x] = srcTable[x];
328 for ( y=0; y < _original_data.height(); ++y ) 329 for ( y=0; y < _original_data.height(); ++y )
329 { 330 {
330 srcData = (unsigned char *)_original_data.scanLine(y); 331 srcData = (unsigned char *)_original_data.scanLine(y);
331 for ( x=0; x < _original_data.width(); ++x ) 332 for ( x=0; x < _original_data.width(); ++x )
332 { 333 {
333 destData = (unsigned char *)dest.scanLine(_original_data.width()-x-1); 334 destData = (unsigned char *)dest.scanLine(_original_data.width()-x-1);
334 destData[y] = srcData[x]; 335 destData[y] = srcData[x];
335 } 336 }
336 } 337 }
337 break; 338 break;
338 default: 339 default:
339 dest = _original_data; 340 dest = _original_data;
340 break; 341 break;
341 } 342 }
342 343
343 } 344 }
344 _newImage = true; 345 _newImage = true;
345 _image_data = dest; 346 _image_data = dest;
346} 347}
347 348
348// yes - sorry - it is NOT gamma it is just BRIGHTNESS. Alwin 349// yes - sorry - it is NOT gamma it is just BRIGHTNESS. Alwin
349void OImageScrollView::apply_gamma(int aValue) 350void OImageScrollView::apply_gamma(int aValue)
350{ 351{
351 if (!_image_data.size().isValid()) return; 352 if (aValue==0 || !_image_data.size().isValid()) return;
352 float percent = ((float)aValue/100.0); 353 float percent = ((float)aValue/100.0);
354 /* make sure working on a copy */
355 _image_data.detach();
353 356
354 int segColors = _image_data.depth() > 8 ? 256 : _image_data.numColors(); 357 int segColors = _image_data.depth() > 8 ? 256 : _image_data.numColors();
355 /* must be - otherwise it displays some ... strange colors */ 358 /* must be - otherwise it displays some ... strange colors */
356 if (segColors<256) segColors=256; 359 if (segColors<256) segColors=256;
357 360
358 unsigned char *segTbl = new unsigned char[segColors]; 361 unsigned char *segTbl = new unsigned char[segColors];
359 int pixels = _image_data.depth()>8?_image_data.width()*_image_data.height() : _image_data.numColors(); 362 int pixels = _image_data.depth()>8?_image_data.width()*_image_data.height() : _image_data.numColors();
360 363
361 364
362 bool brighten = (percent >= 0); 365 bool brighten = (percent >= 0);
363 if ( percent < 0 ) { 366 if ( percent < 0 ) {
364 percent = -percent; 367 percent = -percent;
365 } 368 }
366 369
367 unsigned int *data = _image_data.depth() > 8 ? (unsigned int *)_image_data.bits() : 370 unsigned int *data = _image_data.depth() > 8 ? (unsigned int *)_image_data.bits() :
368 (unsigned int *)_image_data.colorTable(); 371 (unsigned int *)_image_data.colorTable();
369 372
370 int tmp = 0; 373 int tmp = 0;
371 374
372 if (brighten) { 375 if (brighten) {
373 for ( int i=0; i < segColors; ++i ) 376 for ( int i=0; i < segColors; ++i )
374 { 377 {
375 tmp = (int)(i*percent); 378 tmp = (int)(i*percent);
376 if ( tmp > 255 ) 379 if ( tmp > 255 )
377 tmp = 255; 380 tmp = 255;
378 segTbl[i] = tmp; 381 segTbl[i] = tmp;
379 } 382 }
380 } else { 383 } else {
381 for ( int i=0; i < segColors; ++i ) 384 for ( int i=0; i < segColors; ++i )
382 { 385 {
383 tmp = (int)(i*percent); 386 tmp = (int)(i*percent);
384 if ( tmp < 0 ) 387 if ( tmp < 0 )
385 tmp = 0; 388 tmp = 0;
386 segTbl[i] = tmp; 389 segTbl[i] = tmp;
387 } 390 }
388 } 391 }
389 if (brighten) { 392 if (brighten) {
390 for ( int i=0; i < pixels; ++i ) 393 for ( int i=0; i < pixels; ++i )
391 { 394 {
392 int r = qRed(data[i]); 395 int r = qRed(data[i]);
393 int g = qGreen(data[i]); 396 int g = qGreen(data[i]);
394 int b = qBlue(data[i]); 397 int b = qBlue(data[i]);
395 int a = qAlpha(data[i]); 398 int a = qAlpha(data[i]);
396 r = r + segTbl[r] > 255 ? 255 : r + segTbl[r]; 399 r = r + segTbl[r] > 255 ? 255 : r + segTbl[r];
397 g = g + segTbl[g] > 255 ? 255 : g + segTbl[g]; 400 g = g + segTbl[g] > 255 ? 255 : g + segTbl[g];
398 b = b + segTbl[b] > 255 ? 255 : b + segTbl[b]; 401 b = b + segTbl[b] > 255 ? 255 : b + segTbl[b];
399 data[i] = qRgba(r, g, b,a); 402 data[i] = qRgba(r, g, b,a);
400 } 403 }
401 } else { 404 } else {
402 for ( int i=0; i < pixels; ++i ) 405 for ( int i=0; i < pixels; ++i )
403 { 406 {
404 int r = qRed(data[i]); 407 int r = qRed(data[i]);
405 int g = qGreen(data[i]); 408 int g = qGreen(data[i]);
406 int b = qBlue(data[i]); 409 int b = qBlue(data[i]);
407 int a = qAlpha(data[i]); 410 int a = qAlpha(data[i]);
408 r = r - segTbl[r] < 0 ? 0 : r - segTbl[r]; 411 r = r - segTbl[r] < 0 ? 0 : r - segTbl[r];
409 g = g - segTbl[g] < 0 ? 0 : g - segTbl[g]; 412 g = g - segTbl[g] < 0 ? 0 : g - segTbl[g];
410 b = b - segTbl[b] < 0 ? 0 : b - segTbl[b]; 413 b = b - segTbl[b] < 0 ? 0 : b - segTbl[b];
411 data[i] = qRgba(r, g, b, a); 414 data[i] = qRgba(r, g, b, a);
412 } 415 }
413 } 416 }
414 delete [] segTbl; 417 delete [] segTbl;
415} 418}
416 419
417const int OImageScrollView::Intensity()const 420const int OImageScrollView::Intensity()const
418{ 421{
419 return _intensity; 422 return _intensity;
420} 423}
421 424
422int OImageScrollView::setIntensity(int value,bool reload) 425int OImageScrollView::setIntensity(int value,bool reload)
423{ 426{
424 int oldi = _intensity; 427 int oldi = _intensity;
425 _intensity = value; 428 _intensity = value;
426 if (!_pdata.size().isValid()) { 429 if (!_pdata.size().isValid()) {
427 return _intensity; 430 return _intensity;
428 } 431 }
429 432
430 if (!reload) { 433 if (!reload) {
431 _image_data = _pdata.convertToImage(); 434 _image_data = _pdata.convertToImage();
432 apply_gamma(_intensity-oldi); 435 apply_gamma(_intensity-oldi);
433 _pdata.convertFromImage(_image_data); 436 _pdata.convertFromImage(_image_data);
434 /* 437 /*
435 * invalidate 438 * invalidate
436 */ 439 */
437 _image_data=QImage(); 440 _image_data=QImage();
438 if (isVisible()) { 441 if (isVisible()) {
439 updateContents(contentsX(),contentsY(),width(),height()); 442 updateContents(contentsX(),contentsY(),width(),height());
440 } 443 }
441 } else { 444 } else {
442 _newImage = true; 445 _newImage = true;
443 generateImage(); 446 generateImage();
444 } 447 }
445 return _intensity; 448 return _intensity;
446} 449}
447 450
448void OImageScrollView::generateImage() 451void OImageScrollView::generateImage()