33
33
import static javafx .scene .web .WebEvent .STATUS_CHANGED ;
34
34
import static javafx .scene .web .WebEvent .VISIBILITY_CHANGED ;
35
35
36
- import com .sun .javafx .tk .Toolkit ;
37
36
import com .sun .webkit .UIClient ;
38
37
import com .sun .webkit .WebPage ;
39
38
import com .sun .webkit .graphics .WCImage ;
40
39
import com .sun .webkit .graphics .WCRectangle ;
41
- import java .awt .AlphaComposite ;
42
- import java .awt .Graphics2D ;
43
- import java .awt .image .BufferedImage ;
44
- import java .awt .image .DataBufferInt ;
45
- import java .awt .image .SampleModel ;
46
- import java .awt .image .SinglePixelPackedSampleModel ;
47
40
import java .io .File ;
48
41
import java .io .IOException ;
49
42
import java .io .UnsupportedEncodingException ;
50
43
import java .nio .ByteBuffer ;
51
- import java .nio .IntBuffer ;
52
44
import java .security .AccessControlContext ;
53
45
import java .security .AccessController ;
54
46
import java .security .PrivilegedAction ;
58
50
import java .util .Map ;
59
51
import javafx .event .EventHandler ;
60
52
import javafx .geometry .Rectangle2D ;
61
- import javafx .scene .image .Image ;
62
- import javafx .scene .image .PixelFormat ;
63
- import javafx .scene .image .PixelReader ;
64
- import javafx .scene .image .WritablePixelFormat ;
65
53
import javafx .scene .input .ClipboardContent ;
66
54
import javafx .scene .input .DataFormat ;
67
55
import javafx .scene .input .Dragboard ;
@@ -342,7 +330,7 @@ private static DataFormat getDataFormat(String mimeType) {
342
330
//never happens
343
331
}
344
332
}
345
- if (image != null ) {
333
+ if (image != null && ! image . isNull () ) {
346
334
ByteBuffer dragImageOffset = ByteBuffer .allocate (8 );
347
335
dragImageOffset .rewind ();
348
336
dragImageOffset .putInt (imageOffsetX );
@@ -364,26 +352,18 @@ private static DataFormat getDataFormat(String mimeType) {
364
352
//QuantumClipboard.putContent have to be rewritten in Glass manner
365
353
//with postponed data requests (DelayedCallback data object).
366
354
if (isImageSource ) {
367
- Object platformImage = image .getWidth () > 0 && image .getHeight () > 0 ?
368
- image .getPlatformImage () : null ;
369
355
String fileExtension = image .getFileExtension ();
370
- if (platformImage != null ) {
371
- try {
372
- File temp = File .createTempFile ("jfx" , "." + fileExtension );
373
- temp .deleteOnExit ();
374
- ImageIO .write (
375
- toBufferedImage (Toolkit .getImageAccessor ().fromPlatformImage (
376
- Toolkit .getToolkit ().loadPlatformImage (
377
- platformImage
378
- )
379
- )),
380
- fileExtension ,
381
- temp );
382
- content .put (DataFormat .FILES , Arrays .asList (temp ));
383
- } catch (IOException | SecurityException e ) {
384
- //That is ok. It was just an attempt.
385
- //e.printStackTrace();
386
- }
356
+ try {
357
+ File temp = File .createTempFile ("jfx" , "." + fileExtension );
358
+ temp .deleteOnExit ();
359
+ ImageIO .write (
360
+ image .toBufferedImage (),
361
+ fileExtension ,
362
+ temp );
363
+ content .put (DataFormat .FILES , Arrays .asList (temp ));
364
+ } catch (IOException | SecurityException e ) {
365
+ //That is ok. It was just an attempt.
366
+ //e.printStackTrace();
387
367
}
388
368
}
389
369
}
@@ -403,143 +383,4 @@ private static DataFormat getDataFormat(String mimeType) {
403
383
return accessor .getView () != null && content != null ;
404
384
}
405
385
406
- private static int
407
- getBestBufferedImageType (PixelFormat <?> fxFormat , BufferedImage bimg ,
408
- boolean isOpaque )
409
- {
410
- if (bimg != null ) {
411
- int bimgType = bimg .getType ();
412
- if (bimgType == BufferedImage .TYPE_INT_ARGB ||
413
- bimgType == BufferedImage .TYPE_INT_ARGB_PRE ||
414
- (isOpaque &&
415
- (bimgType == BufferedImage .TYPE_INT_BGR ||
416
- bimgType == BufferedImage .TYPE_INT_RGB )))
417
- {
418
- // We will allow the caller to give us a BufferedImage
419
- // that has an alpha channel, but we might not otherwise
420
- // construct one ourselves.
421
- // We will also allow them to choose their own premultiply
422
- // type which may not match the image.
423
- // If left to our own devices we might choose a more specific
424
- // format as indicated by the choices below.
425
- return bimgType ;
426
- }
427
- }
428
- switch (fxFormat .getType ()) {
429
- default :
430
- case BYTE_BGRA_PRE :
431
- case INT_ARGB_PRE :
432
- return BufferedImage .TYPE_INT_ARGB_PRE ;
433
- case BYTE_BGRA :
434
- case INT_ARGB :
435
- return BufferedImage .TYPE_INT_ARGB ;
436
- case BYTE_RGB :
437
- return BufferedImage .TYPE_INT_RGB ;
438
- case BYTE_INDEXED :
439
- return (fxFormat .isPremultiplied ()
440
- ? BufferedImage .TYPE_INT_ARGB_PRE
441
- : BufferedImage .TYPE_INT_ARGB );
442
- }
443
- }
444
-
445
- private static WritablePixelFormat <IntBuffer >
446
- getAssociatedPixelFormat (BufferedImage bimg )
447
- {
448
- switch (bimg .getType ()) {
449
- // We lie here for xRGB, but we vetted that the src data was opaque
450
- // so we can ignore the alpha. We use ArgbPre instead of Argb
451
- // just to get a loop that does not have divides in it if the
452
- // PixelReader happens to not know the data is opaque.
453
- case BufferedImage .TYPE_INT_RGB :
454
- case BufferedImage .TYPE_INT_ARGB_PRE :
455
- return PixelFormat .getIntArgbPreInstance ();
456
- case BufferedImage .TYPE_INT_ARGB :
457
- return PixelFormat .getIntArgbInstance ();
458
- default :
459
- // Should not happen...
460
- throw new InternalError ("Failed to validate BufferedImage type" );
461
- }
462
- }
463
-
464
- private static boolean checkFXImageOpaque (PixelReader pr , int iw , int ih ) {
465
- for (int x = 0 ; x < iw ; x ++) {
466
- for (int y = 0 ; y < ih ; y ++) {
467
- Color color = pr .getColor (x ,y );
468
- if (color .getOpacity () != 1.0 ) {
469
- return false ;
470
- }
471
- }
472
- }
473
- return true ;
474
- }
475
-
476
- private static BufferedImage fromFXImage (Image img , BufferedImage bimg ) {
477
- PixelReader pr = img .getPixelReader ();
478
- if (pr == null ) {
479
- return null ;
480
- }
481
- int iw = (int ) img .getWidth ();
482
- int ih = (int ) img .getHeight ();
483
- PixelFormat <?> fxFormat = pr .getPixelFormat ();
484
- boolean srcPixelsAreOpaque = false ;
485
- switch (fxFormat .getType ()) {
486
- case INT_ARGB_PRE :
487
- case INT_ARGB :
488
- case BYTE_BGRA_PRE :
489
- case BYTE_BGRA :
490
- // Check fx image opacity only if
491
- // supplied BufferedImage is without alpha channel
492
- if (bimg != null &&
493
- (bimg .getType () == BufferedImage .TYPE_INT_BGR ||
494
- bimg .getType () == BufferedImage .TYPE_INT_RGB )) {
495
- srcPixelsAreOpaque = checkFXImageOpaque (pr , iw , ih );
496
- }
497
- break ;
498
- case BYTE_RGB :
499
- srcPixelsAreOpaque = true ;
500
- break ;
501
- }
502
- int prefBimgType = getBestBufferedImageType (pr .getPixelFormat (), bimg , srcPixelsAreOpaque );
503
- if (bimg != null ) {
504
- int bw = bimg .getWidth ();
505
- int bh = bimg .getHeight ();
506
- if (bw < iw || bh < ih || bimg .getType () != prefBimgType ) {
507
- bimg = null ;
508
- } else if (iw < bw || ih < bh ) {
509
- Graphics2D g2d = bimg .createGraphics ();
510
- g2d .setComposite (AlphaComposite .Clear );
511
- g2d .fillRect (0 , 0 , bw , bh );
512
- g2d .dispose ();
513
- }
514
- }
515
- if (bimg == null ) {
516
- bimg = new BufferedImage (iw , ih , prefBimgType );
517
- }
518
- DataBufferInt db = (DataBufferInt )bimg .getRaster ().getDataBuffer ();
519
- int data [] = db .getData ();
520
- int offset = bimg .getRaster ().getDataBuffer ().getOffset ();
521
- int scan = 0 ;
522
- SampleModel sm = bimg .getRaster ().getSampleModel ();
523
- if (sm instanceof SinglePixelPackedSampleModel ) {
524
- scan = ((SinglePixelPackedSampleModel )sm ).getScanlineStride ();
525
- }
526
-
527
- WritablePixelFormat <IntBuffer > pf = getAssociatedPixelFormat (bimg );
528
- pr .getPixels (0 , 0 , iw , ih , pf , data , offset , scan );
529
- return bimg ;
530
- }
531
-
532
- // Method to implement the following via reflection:
533
- // SwingFXUtils.fromFXImage(img, null)
534
- public static BufferedImage toBufferedImage (Image img ) {
535
- try {
536
- return fromFXImage (img , null );
537
- } catch (Exception ex ) {
538
- ex .printStackTrace (System .err );
539
- }
540
-
541
- // return null upon any exception
542
- return null ;
543
- }
544
-
545
386
}
0 commit comments