nick zoum nick zoum - 1 year ago 114
Java Question

How to bend an Image in java

Is there any way to bend a

in Java?

I thought that if I crop the image into smaller pieces and rotate them then i would essentially bend the image but it doesn't seem to work.

Here is the method i created:

* This is a recursive method that will accept an image the point where the bending will start and the point where the bending will end, as well as the angle of bending
* @param original:the original image
* @param startingPoint: the point where the bending should start
* @param endingPoint: the point where the bending should end
* @param radiands: the angle
* @return the bent image
public static BufferedImage getBentImage(BufferedImage original, int startingPoint, int endingPoint, double radians) {
if (startingPoint >= endingPoint)
return original;

int type = BufferedImage.TYPE_INT_ARGB;
int width = original.getWidth();
int height = original.getHeight();

BufferedImage crop = original.getSubimage(0, 0, startingPoint, height);
BufferedImage crop0 = original.getSubimage(startingPoint, 0, width - startingPoint, height);
BufferedImage bendCrop = new BufferedImage(width, height, type);
BufferedImage image = new BufferedImage(width, height, type);

AffineTransform rotation = new AffineTransform();
rotation.translate(0, 0);

Graphics2D g = bendCrop.createGraphics();
g.drawImage(crop0, rotation, null);

g = image.createGraphics();
g.drawImage(crop, 0, 0, null);
g.drawImage(bendCrop, startingPoint, 0, null);

return getBentImage(image, startingPoint + 1, endingPoint, radians);

This is the original Image:

original Image

And this is the result of this
getBentImage(image, 200, 220, Math.toRadians(1))


I was expecting something closer to:

expected result

Any ideas on how to actually implement a

Answer Source

As suggested in the comments, a simple approach is to divide the image into 3 parts:

  1. Identical to the original.
  2. Bent according to the bending transformation.
  3. Constant diagonal continuation.

Here is a quick and a bit messy example that shows the original shape and the resulting shape below it. I just used a label icon for the images instead of doing custom painting. (Also I didn't adhere to the Java naming conventions with final variables because it's math and not typical coding.)

Since there are quite a few variables in the calculation code, I added a sketch at the end that shows what the variables represent.

enter image description here

public class Main extends JFrame {

    static BufferedImage image;

    public static void main(String[] args) {

        try {
            image ="img.png"));
        } catch (IOException e) {
        new Main();

    public Main() {

        getContentPane().setLayout(new BorderLayout(5, 10));
        BufferedImage img2 = transform(15, 100, 300);

        JLabel label1 = new JLabel(new ImageIcon(image));
        add(label1, BorderLayout.NORTH);

        JLabel label2 = new JLabel(new ImageIcon(img2));


    static BufferedImage transform(int t, int x1, int x2) {

        final double TH = Math.toRadians(t);
        final int D = x2 - x1;
        final int W = image.getWidth();
        final int H = image.getHeight();

        final int dD = (int) (D / (2 * TH) * Math.sin(2 * TH));
        final int dH = (int) (D / TH * Math.pow(Math.sin(TH), 2));
        final int pH = (int) ((W - x2) * Math.tan(2 * TH));

        final int width = W - (D - dD);
        final int height = (int) (H + dH + pH);

        System.out.println(W + " " + H + " -> " + width + " " + height);

        BufferedImage img2 = new BufferedImage(width, height, image.getType());

        for (int x = 0; x < x1; x++) {
            for (int y = 0; y < H; y++) {
                int rgb = image.getRGB(x, y);
                img2.setRGB(x, y, rgb);

        for (int x = x1; x < x2; x++) {
            for (int y = 0; y < H; y++) {
                int rgb = image.getRGB(x, y);
                int dx = (int) (D / (2 * TH) * Math.sin(2 * (x-x1) * TH / D));
                int dy = (int) (D / TH * Math.pow(Math.sin((x-x1) * TH / D), 2));
                img2.setRGB(x1 + dx, y + dy, rgb);

        for (int x = x2; x < W; x++) {
            for (int y = 0; y < H; y++) {
                int rgb = image.getRGB(x, y);
                int dp = (int) ((x - x2) * Math.tan(2 * TH));
                img2.setRGB(x - (D - dD), y + dH + dp, rgb);

        return img2;

enter image description here

As for the calculations, I'll leave it for you as homework; it's just geometry/trigonometry which belongs on Math.SE more than on SO. If you can't figure it out I'll give you a direction.

Note that this method might not be fast at all and could certainly be optimized, I'll leave that to you also.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download