Advertisement
jonahbron

SWT/AWT Image Scaling

May 16th, 2014
398
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 10.52 KB | None | 0 0
  1. package bz;
  2.  
  3. import java.awt.Graphics2D;
  4. import java.awt.RenderingHints;
  5. import java.awt.image.BufferedImage;
  6. import java.awt.image.DirectColorModel;
  7. import java.awt.image.IndexColorModel;
  8. import java.awt.image.WritableRaster;
  9. import java.io.File;
  10. import java.io.FileInputStream;
  11. import java.io.FileOutputStream;
  12. import java.io.IOException;
  13.  
  14. import org.eclipse.swt.SWT;
  15. import org.eclipse.swt.SWTException;
  16. import org.eclipse.swt.graphics.ImageData;
  17. import org.eclipse.swt.graphics.ImageLoader;
  18. import org.eclipse.swt.graphics.PaletteData;
  19. import org.eclipse.swt.graphics.RGB;
  20.  
  21. import bz.command.OpenErrorWindow;
  22.  
  23. /**
  24.  * Represents a Thumbnail in the workspace.  Wraps an Image object.
  25.  *
  26.  * @author Jonah Dahlquist <jonah@nucleussystems.com>
  27.  * @license public domain
  28.  */
  29. public class Thumbnail implements Comparable<Thumbnail>
  30. {
  31.  
  32.    
  33.     // Contains the thumbnail data if it has been generated and not cached
  34.     protected ImageData thumbData;
  35.    
  36.     // Contains the location of the thumbnail data if it has been cached
  37.     protected File thumbFile;
  38.    
  39.     // Indicates if the thumbnail is in memory.  Read by getThumbData()
  40.     protected boolean thumbDataInMemory = false;
  41.    
  42.     // Indicates if the thumbnail is cached
  43.     protected boolean thumbDataCached = false;
  44.    
  45.     // Flag if file could not be loaded
  46.     protected boolean isCorrupt = false;
  47.    
  48.     // Flag if cursor is hovering over
  49.     private boolean over_ = false;
  50.    
  51.     // Flag if thumbnail is selected
  52.     private boolean selected_ = false;
  53.    
  54.     // Wrapped image
  55.     private Image image_;
  56.    
  57.     // Thumbnail area
  58.     private Rectangle eventBox_ = new Rectangle(0, 0, 0, 0);
  59.    
  60.     /**
  61.      * Create new thumbnail
  62.      *
  63.      * @param Image
  64.      */
  65.     public Thumbnail(Image image)
  66.     {
  67.         image_ = image;
  68.     }
  69.    
  70.     /**
  71.      * Cursor is (not) over
  72.      *
  73.      * @param boolean
  74.      */
  75.     public void setOver(boolean over)
  76.     {
  77.         over_ = over;
  78.     }
  79.    
  80.     /**
  81.      * Cursor is (not) selected
  82.      * @param selected
  83.      */
  84.     public void setSelected(boolean selected)
  85.     {
  86.         selected_ = selected;
  87.     }
  88.    
  89.     /**
  90.      * Set thumbnail area
  91.      *
  92.      * @param Rectangle
  93.      */
  94.     public void setArea(Rectangle eventBox)
  95.     {
  96.         eventBox_ = eventBox;
  97.     }
  98.    
  99.     /**
  100.      * Is cursor over?
  101.      *
  102.      * @return boolean
  103.      */
  104.     public boolean getOver()
  105.     {
  106.         return over_;
  107.     }
  108.    
  109.     /**
  110.      * Is thumbnail selected?
  111.      *
  112.      * @return boolean
  113.      */
  114.     public boolean getSelected()
  115.     {
  116.         return selected_;
  117.     }
  118.    
  119.     /**
  120.      * Get wrapped image
  121.      *
  122.      * @return Image
  123.      */
  124.     public Image getImage()
  125.     {
  126.         return image_;
  127.     }
  128.    
  129.     /**
  130.      * Get thumbnail area
  131.      *
  132.      * @return Rectangle
  133.      */
  134.     public Rectangle getArea()
  135.     {
  136.         return eventBox_;
  137.     }
  138.    
  139.     /**
  140.      * Gets the image data from the file.  This allows generation of
  141.      * thumbnails, view of the image, etc.
  142.      *
  143.      * @see java.awt.Image
  144.      * @return The image data as java.awt.Image
  145.      */
  146.     public BufferedImage getImageData()
  147.     {
  148.         return image_.getImageData();
  149.     }
  150.    
  151.     /**
  152.      * Gets the image data at the specified resolution
  153.      *
  154.      * @param Integer width
  155.      * @return BufferedImage resized image
  156.      */
  157.     public ImageData getImageData(Integer width)
  158.     {
  159.         return resizeImage(getImageData(), width);
  160.     }
  161.    
  162.     /**
  163.      * Gets the image thumbnail data from the image file, memory, or the cache.
  164.      *
  165.      * @see java.awt.Image
  166.      * @return The thumbnail data as java.awt.Image
  167.      */
  168.     public ImageData getThumbData()
  169.     {
  170.         generateThumb();
  171.         if (thumbDataCached && !thumbDataInMemory){
  172.             try {
  173.                 FileInputStream fileStream = new FileInputStream(thumbFile);
  174.                 thumbData = new ImageData(fileStream);
  175.                 fileStream.close();
  176.                 thumbDataInMemory = true;
  177.             } catch (IOException exception) {
  178.                 thumbFile.delete();
  179.                 thumbDataCached = false;
  180.                 isCorrupt = true;
  181.                 Logger.log("Failed to load thumbnail from cache");
  182.             } catch (SWTException exception) {
  183.                 thumbFile.delete();
  184.                 thumbDataCached = false;
  185.                 isCorrupt = true;
  186.                 Logger.log("Failed to load thumbnail from cache");
  187.             } catch (NullPointerException exception) {
  188.                 thumbDataCached = false;
  189.                 Logger.log("Failed to load thumbnail from cache");
  190.             }
  191.         }
  192.         return thumbData;
  193.     }
  194.    
  195.     /**
  196.      * Generates the thumbnail data from the image file and saves it to memory
  197.      */
  198.     private void generateThumb()
  199.     {
  200.         if (!thumbDataInMemory && !thumbDataCached) {
  201.             Integer width = Integer.valueOf(Config.getInstance().getInt(Config.THUMB_SIZE, Config.THUMB_SIZE_DEFAULT));
  202.             thumbData = getImageData(width);
  203.             thumbDataInMemory = true;
  204.         }
  205.     }
  206.    
  207.     /**
  208.      * Resized the passed BufferedImage to the specified width and height
  209.      *
  210.      * @param BufferedImage image
  211.      * @param Integer width
  212.      * @return BufferedImage the resized image
  213.      */
  214.     private ImageData resizeImage(BufferedImage imageData, Integer width)
  215.     {
  216.         if (imageData == null) return null;
  217.         //org.eclipse.swt.graphics.Image image = new org.eclipse.swt.graphics.Image(null, imageData);
  218.        
  219.         BufferedImage tmp = new BufferedImage(width, width, BufferedImage.TYPE_INT_RGB);
  220.        
  221.         Graphics2D g2 = tmp.createGraphics();
  222.         g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
  223.         g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
  224.        
  225.         if (imageData.getWidth() < imageData.getHeight()) {
  226.            
  227.             Integer diff = imageData.getHeight() - imageData.getWidth();
  228.             Integer halfDiff = diff / 2;
  229.            
  230.             g2.drawImage(imageData, 0, 0, width, width, 0, halfDiff, imageData.getWidth(), halfDiff + (imageData.getHeight() - diff), null);
  231.            
  232.         } else if (imageData.getWidth() > imageData.getHeight()) {
  233.            
  234.             Integer diff = imageData.getWidth() - imageData.getHeight();
  235.             Integer halfDiff = diff / 2;
  236.            
  237.             g2.drawImage(imageData, 0, 0, width, width, halfDiff, 0, halfDiff + (imageData.getWidth() - diff), imageData.getHeight(), null);
  238.            
  239.         } else {
  240.            
  241.             g2.drawImage(imageData, 0, 0, width, width, 0, 0, imageData.getWidth(), imageData.getHeight(), null);
  242.         }
  243.         g2.dispose();
  244.         return convertToSWT(tmp);
  245.     }
  246.    
  247.     /**
  248.      * Takes the thumbnail and places it in a temporary file.  A reference to
  249.      * the file is placed in private
  250.      */
  251.     public void cacheThumb()
  252.     {
  253.         if (!thumbDataCached) {
  254.             createCacheFile();
  255.            
  256.             try {
  257.                 ImageLoader loader = new ImageLoader();
  258.                 loader.data = new ImageData[] {getThumbData()};
  259.                 FileOutputStream outputStream = new FileOutputStream(thumbFile);
  260.                 loader.save(outputStream, SWT.IMAGE_JPEG);
  261.                 outputStream.close();
  262.                 thumbDataCached = true;
  263.             } catch (IOException exception) {
  264.                 Logger.log("Failed to save thumbnail cache");
  265.             } catch (NullPointerException exception) {
  266.                 Logger.log("Failed to save thumbnail cache");
  267.             } catch (SWTException exception) {
  268.                 Logger.log("Failed to save thumbnail cache");
  269.             }
  270.         }
  271.     }
  272.    
  273.     /**
  274.      * Create a new unique file in the THUMB_DIR for this thumbnail cache
  275.      */
  276.     protected void createCacheFile()
  277.     {
  278.         if (!thumbDataCached) {
  279.             try {
  280.                 thumbFile = File.createTempFile("bz_", ".jpg");
  281.                 thumbFile.deleteOnExit();
  282.             } catch (IOException exception) {
  283.                 Logger.log("Failed to create thumbnail cache file");
  284.                 Registry.getCommandManager().executeCommand(new OpenErrorWindow(exception));
  285.             }
  286.         }
  287.     }
  288.    
  289.     /**
  290.      * Makes sure the thumbnail has been cached, then removes thumbnail data
  291.      * from memory.
  292.      */
  293.     public void flushThumbData()
  294.     {
  295.         cacheThumb();
  296.         destroyMemory();
  297.     }
  298.    
  299.     /**
  300.      * Deletes thumbnail file from cache, and destroys file object
  301.      */
  302.     public void destroyCache()
  303.     {
  304.         if (thumbDataCached) {
  305.             if (thumbFile != null) {
  306.                 thumbFile.delete();
  307.             }
  308.             thumbFile = null;
  309.             thumbDataCached = false;
  310.         }
  311.     }
  312.    
  313.     /**
  314.      * Deletes thumbnail from memory
  315.      */
  316.     public void destroyMemory()
  317.     {
  318.         if (thumbDataInMemory) {
  319.             thumbData = null;
  320.             thumbDataInMemory = false;
  321.         }
  322.     }
  323.    
  324.     /**
  325.      * Check if thumbnail has been generated yet
  326.      *
  327.      * @return boolean
  328.      */
  329.     public boolean thumbIsGenerated()
  330.     {
  331.         return ((thumbDataInMemory && (thumbData != null)) || thumbDataCached);
  332.     }
  333.    
  334.     /**
  335.      * Check if thumbnail is stored in memory
  336.      *
  337.      * @return boolean
  338.      */
  339.     public boolean thumbInMemory()
  340.     {
  341.         return thumbDataInMemory;
  342.     }
  343.    
  344.     /**
  345.      * Convert AWT to SWT
  346.      *
  347.      * @param BufferedImage
  348.      * @return ImageData
  349.      */
  350.     public static ImageData convertToSWT(BufferedImage bufferedImage) {
  351.         if (bufferedImage.getColorModel() instanceof DirectColorModel) {
  352.             DirectColorModel colorModel = (DirectColorModel) bufferedImage.getColorModel();
  353.             PaletteData palette = new PaletteData(
  354.                 colorModel.getRedMask(),
  355.                 colorModel.getGreenMask(),
  356.                 colorModel.getBlueMask()
  357.             );
  358.             ImageData data = new ImageData(
  359.                 bufferedImage.getWidth(),
  360.                 bufferedImage.getHeight(), colorModel.getPixelSize(),
  361.                 palette
  362.             );
  363.             WritableRaster raster = bufferedImage.getRaster();
  364.             int[] pixelArray = new int[3];
  365.             for (int y = 0; y < data.height; y++) {
  366.                 for (int x = 0; x < data.width; x++) {
  367.                     raster.getPixel(x, y, pixelArray);
  368.                     int pixel = palette.getPixel(
  369.                         new RGB(pixelArray[0], pixelArray[1], pixelArray[2])
  370.                     );
  371.                     data.setPixel(x, y, pixel);
  372.                 }
  373.             }
  374.             return data;
  375.         } else if (bufferedImage.getColorModel() instanceof IndexColorModel) {
  376.             IndexColorModel colorModel = (IndexColorModel) bufferedImage.getColorModel();
  377.             int size = colorModel.getMapSize();
  378.             byte[] reds = new byte[size];
  379.             byte[] greens = new byte[size];
  380.             byte[] blues = new byte[size];
  381.             colorModel.getReds(reds);
  382.             colorModel.getGreens(greens);
  383.             colorModel.getBlues(blues);
  384.             RGB[] rgbs = new RGB[size];
  385.             for (int i = 0; i < rgbs.length; i++) {
  386.                 rgbs[i] = new RGB(reds[i] & 0xFF, greens[i] & 0xFF, blues[i] & 0xFF);
  387.             }
  388.             PaletteData palette = new PaletteData(rgbs);
  389.             ImageData data = new ImageData(
  390.                 bufferedImage.getWidth(),
  391.                 bufferedImage.getHeight(),
  392.                 colorModel.getPixelSize(),
  393.                 palette
  394.             );
  395.             data.transparentPixel = colorModel.getTransparentPixel();
  396.             WritableRaster raster = bufferedImage.getRaster();
  397.             int[] pixelArray = new int[1];
  398.             for (int y = 0; y < data.height; y++) {
  399.                 for (int x = 0; x < data.width; x++) {
  400.                     raster.getPixel(x, y, pixelArray);
  401.                     data.setPixel(x, y, pixelArray[0]);
  402.                 }
  403.             }
  404.             return data;
  405.         }
  406.         return null;
  407.     }
  408.    
  409.     /**
  410.      * Check if file couldn't be loaded
  411.      *
  412.      * @return boolean
  413.      */
  414.     public boolean isCorrupt()
  415.     {
  416.         return isCorrupt;
  417.     }
  418.    
  419.     /**
  420.      * Comparison function, for sorting
  421.      *
  422.      * @return int
  423.      */
  424.     public int compareTo(Thumbnail thumbnail2) {
  425.         return image_.compareTo(thumbnail2.getImage());
  426.     }
  427.    
  428.     public boolean equals(Object item2) {
  429.         return image_.equals(item2);
  430.     }
  431. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement