Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2014 Aritz Lopez
   *
   *    Licensed under the Apache License, Version 2.0 (the "License");
   *    you may not use this file except in compliance with the License.
   *    You may obtain a copy of the License at
   *
   *        http://www.apache.org/licenses/LICENSE-2.0
   *
  *    Unless required by applicable law or agreed to in writing, software
  *    distributed under the License is distributed on an "AS IS" BASIS,
  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  *    See the License for the specific language governing permissions and
  *    limitations under the License.
  */
 
 package io.github.aritzhack.aritzh.awt.util;
 
 
Utility class to handle things related to Sprites, such as scaling

Author(s):
Aritz Lopez
 
 public class SpriteUtil {

    
Creates a new Sprite with a cicle drawn onto it

Parameters:
diameter The diameter of the circle (will be the width and height of the sprite)
color The color of the circle (in ARGB format: 0xAARRGGBB)
lineWidth The thickness of the circle. Warning: if thickness is bigger than 1, it will not draw a perfectly filled circle
Returns:
A new Sprite with a circle drawn onto it
 
     public static Sprite circle(int diameterint colorint lineWidth) {
 
         int[] pix = new int[diameter * diameter];
 
         for (int i = 0; i < lineWidthi++) {
             drawCircle(pixdiameter - idiametercolor);
         }
 
         return new Sprite(diameterdiameterpix);
     }
 
     private static void drawCircle(int[] pixint diameterint widthint color) {
 
         int center = width / 2;
         int radius = diameter / 2 - 1;
 
         int d = (5 - (radius * 4)) / 4;
         int x = 0;
         int y = radius;
 
         do {
             pix[center + x + (center + y) * width] = color;
             pix[center + x + (center - y) * width] = color;
             pix[center - x + (center + y) * width] = color;
             pix[center - x + (center - y) * width] = color;
             pix[center + y + (center + x) * width] = color;
             pix[center + y + (center - x) * width] = color;
             pix[center - y + (center + x) * width] = color;
             pix[center - y + (center - x) * width] = color;
 
             if (d < 0) {
                 d += 2 * x + 1;
             } else {
                 d += 2 * (x - y) + 1;
                 y--;
             }
             x++;
         } while (x <= y);
     }

    
Scales an image by a factor, using the given method

Parameters:
original The sprite to scale
scale The factor by which the sprite should be scaled
method The scaling method
Returns:
The scaled sprite
 
     public static Sprite scale(Sprite originalfloat scaleScalingMethod method) {
         if (scale == 1.0f) return original.copy();
 
         switch (method) {
             case :
                 return scaleNearest(originalscale);
             case :
                 return scaleBilinear(originalscale);
         }
 
         return null;
     }
 
    private static Sprite scaleNearest(Sprite originalfloat scale) {
        int newWidth = (int) (original.getWidth() * scale);
        int newHeight = (int) (original.getHeight() * scale);
        int[] newPix = new int[newWidth * newHeight];
        int x_ratio = (original.getWidth() << 16) / newWidth + 1;
        int y_ratio = (original.getHeight() << 16) / newHeight + 1;
        for (int i = 0; i < newHeighti++) {
            for (int j = 0; j < newWidthj++) {
                int x2 = (j * x_ratio >> 16);
                int y2 = (i * y_ratio >> 16);
                newPix[(j + i * newWidth)] = original.getPixels()[(x2 + y2 * original.getWidth())];
            }
        }
        return new Sprite(newWidthnewHeightnewPix);
    }
    private static Sprite scaleBilinear(Sprite originalfloat scale) {
        int newWidth = (int) (original.getWidth() * scale);
        int newHeight = (int) (original.getHeight() * scale);
        int[] newPix = new int[newWidth * newHeight];
        int offset = 0;
        float x_ratio = ((float) (original.getWidth() - 1)) / newWidth;
        float y_ratio = ((float) (original.getWidth() - 1)) / newHeight;
        for (int i = 0; i < newHeighti++) {
            for (int j = 0; j < newWidthj++) {
                int x = (int) (x_ratio * j);
                int y = (int) (y_ratio * i);
                float x_diff = (x_ratio * j) - x;
                float y_diff = (y_ratio * i) - y;
                int index = x + y * original.getWidth();
                int a = original.getPixels()[index];
                int b = original.getPixels()[index + 1];
                int c = original.getPixels()[index + original.getWidth()];
                int d = original.getPixels()[index + original.getWidth() + 1];
                newPix[offset++] = bilinearInterpolate(abcdx_diffy_diff);
            }
        }
        return new Sprite(newWidthnewHeightnewPix);
    }
    private static int bilinearInterpolate(int colorAint colorBint colorCint colorDfloat wfloat h) {
        ARGBColorUtil.Color A = new ARGBColorUtil.Color(colorA);
        ARGBColorUtil.Color B = new ARGBColorUtil.Color(colorB);
        ARGBColorUtil.Color C = new ARGBColorUtil.Color(colorC);
        ARGBColorUtil.Color D = new ARGBColorUtil.Color(colorD);
        // A*(1-w)*(1-h) + B*w*(1-h) + C*h*(1-w) + D*w*h
        int a = (int) (A.a * (1 - w) * (1 - h) + B.a * w * (1 - h) + C.a * h * (1 - w) + D.a * w * h);
        int r = (int) (A.r * (1 - w) * (1 - h) + B.r * w * (1 - h) + C.r * h * (1 - w) + D.r * w * h);
        int g = (int) (A.g * (1 - w) * (1 - h) + B.g * w * (1 - h) + C.g * h * (1 - w) + D.g * w * h);
        int b = (int) (A.b * (1 - w) * (1 - h) + B.b * w * (1 - h) + C.b * h * (1 - w) + D.b * w * h);
        return ARGBColorUtil.getColor(argb);
    }

    
Flips a Sprite horizontally (as if it was seen in a mirror above or below it)

Parameters:
original The sprite to flip horizontally
Returns:
The Sprite flipped
    public static Sprite flipH(Sprite original) {
        int[] newPix = new int[original.getPixels().length];
        for (int y = 0; y < original.getHeight(); y++) {
            int newY = original.getHeight() - y - 1;
            for (int x = 0; x < original.getWidth(); x++) {
                newPix[x + newY * original.getWidth()] = original.getPixels()[x + y * original.getWidth()];
            }
        }
        return new Sprite(original.getWidth(), original.getHeight(), newPix);
    }

    
Flips a Sprite vertically (as if it was seen in a mirror to the left or right)

Parameters:
original The sprite to flip vertically
Returns:
The Sprite flipped
    public static Sprite flipV(Sprite original) {
        int[] newPix = new int[original.getPixels().length];
        for (int x = 0; x < original.getWidth(); x++) {
            int newX = original.getWidth() - x - 1;
            for (int y = 0; y < original.getHeight(); y++) {
                newPix[newX + y * original.getWidth()] = original.getPixels()[x + y * original.getWidth()];
            }
        }
        return new Sprite(original.getWidth(), original.getHeight(), newPix);
    }
    private static int interpolate(int color1int color2int Lfloat l) {
        int a1 = ARGBColorUtil.getAlpha(color1);
        int r1 = ARGBColorUtil.getRed(color1);
        int g1 = ARGBColorUtil.getGreen(color1);
        int b1 = ARGBColorUtil.getBlue(color1);
        int a2 = ARGBColorUtil.getAlpha(color2);
        int r2 = ARGBColorUtil.getRed(color2);
        int g2 = ARGBColorUtil.getGreen(color2);
        int b2 = ARGBColorUtil.getBlue(color2);
        int a3 = (int) (a1 + l * (a2 - a1) / (floatL);
        int r3 = (int) (r1 + l * (r2 - r1) / (floatL);
        int g3 = (int) (g1 + l * (g2 - g1) / (floatL);
        int b3 = (int) (b1 + l * (b2 - b1) / (floatL);
        return ARGBColorUtil.getColor(a3r3g3b3);
    }

    

Rotates a Sprite

Note: If the angle is either 90, 180, 270 or -90, SpriteUtil.rotate90(Sprite, Rotation) will be used instead, since it is much faster

Parameters:
original The sprite to rotate
angle The rotation angle, in degrees
Returns:
The rotated image
    public static Sprite rotate(Sprite originaldouble angle) {
        if (angle == 90.0) return SpriteUtil.rotate90(original.);
        else if (angle == 180.0) return SpriteUtil.rotate90(original.);
        else if (angle == 270.0 || angle == -90.0) return SpriteUtil.rotate90(original.);
        final double radians = Math.toRadians(angle);
        final double cos = Math.cos(radians);
        final double sin = Math.sin(radians);
        int newWidth = (int) (cos * original.getWidth() + sin * original.getHeight());
        int newHeight = (int) (cos * original.getHeight() + sin * original.getWidth());
        int xDelta = (newWidth - original.getWidth()) / 2;
        int yDelta = (newHeight - original.getHeight()) / 2;
        final int[] pixels2 = new int[newWidth * newHeight];
        int centerX = original.getWidth() / 2;
        int centerY = original.getHeight() / 2;
        for (int x = -xDeltax < newWidth - xDeltax++)
            for (int y = -yDeltay < newHeight - yDeltay++) {
                int m = x - centerX;
                int n = y - centerY;
                int j = (int) (m * cos + n * sin + centerX);
                int k = (int) (n * cos - m * sin + centerY);
                if (j >= 0 && j < original.getWidth() && k >= 0 && k < original.getHeight()) {
                    pixels2[(y + yDelta) * newWidth + x + xDelta] = original.getPixels()[k * original.getWidth() + j];
                }
            }
        return new Sprite(newWidthnewHeightpixels2);
    }

    
Rotates an image by multiples of 90 degrees This is a much faster version of SpriteUtil.rotate(Sprite, double)

Parameters:
original The sprite to rotate
angle The rotation angle
Returns:
The rotated sprite
    public static Sprite rotate90(Sprite originalRotation angle) {
        int newWidth = angle == . ? original.getWidth() : original.getHeight();
        int newHeight = angle == . ? original.getHeight() : original.getWidth();
        int[] newPix = new int[original.getPixels().length];
        for (int x = 0; x < original.getWidth(); x++) {
            for (int y = 0; y < original.getHeight(); y++) {
                int newY = angle == . ? x : angle == . ? original.getHeight() - y - 1 : original.getWidth() - x - 1;
                int newX = angle == . ? original.getHeight() - y - 1 : angle == . ? original.getWidth() - x - 1 : y;
                newPix[newX + newY * newWidth] = original.getPixels()[x + y * original.getWidth()];
            }
        }
        return new Sprite(newWidthnewHeightnewPix);
    }

    
Adds a border to a Sprite (the border is added inside, so part of the sprite will be covered)

Parameters:
original The sprite to which the border will be added
color The color of the border (in ARGB format: 0xAARRGGBB)
size The sice of the border, in pixels
Returns:
The sprite with the border
    public static Sprite addBorder(Sprite originalint colorint size) {
        int[] newPix = Arrays.copyOf(original.getPixels(), original.getPixels().length);
        for (int x = 0; x < original.getWidth(); x++) {
            for (int y = 0; y < original.getHeight(); y++) {
                if (x < size || x >= original.getWidth() - size || y < size || y >= original.getHeight() - size) {
                    newPix[x + y * original.getWidth()] = color;
                }
            }
        }
        return new Sprite(original.getWidth(), original.getHeight(), newPix);
    }

    
Multiples of 90 for exact rotations
    public static enum Rotation {
        _90, _180, _270
    }

    
Available scaling methods (Wikipedia page)
    public static enum ScalingMethod {
        
Nearest neighbor interpolation (Wikipedia page)
        NEAREST,
        
Bilinear interpolation (Wikipedia page)
        BILINEAR
    }
New to GrepCode? Check out our FAQ X