How to do perspective transformation of images in java 2d not in jmonkey or java 3d

convert

to

is there something in java advance imaging (vertical shear) to do that
i dont want to do int in 3d , i want it in 2d and totally in java.

also how to make image background remove with java, chose color from image and make it transparent in background.

this is not related to jmonkey engine but a simple 2d transformation question.

You are posting a question on jme forum but you don’t want a jme solution?

I use GIMP when I need to do this, It includes a “color-to-alpha” button for transparency that does just what your’e describing, as well as a bunch of other potentially useful tools for image editing that you may find useful, plus it’s free

What have you tried? Where are you stuck? What part don’t you understand?

The maths is here: Shear mapping - Wikipedia - I’d read it even if you don’t get it. You have to start somewhere… Then read an implementation and put the pieces together. Try to understand it, and not just “do it”.

you can do it using javaFX, it has all necessary 2d/3d transformations for this.

public static BufferedImage colorToAlpha(BufferedImage raw, Color remove)
{
int WIDTH = raw.getWidth();
int HEIGHT = raw.getHeight();
BufferedImage image = new BufferedImage(WIDTH,HEIGHT,BufferedImage.TYPE_INT_ARGB);
int pixels[]=new int[WIDTH*HEIGHT];
raw.getRGB(0, 0, WIDTH, HEIGHT, pixels, 0, WIDTH);
for(int i=0; i<pixels.length;i++)
{
if (pixels[i] == remove.getRGB())
{
pixels[i] = 0x00ffffff;
}
}
image.setRGB(0, 0, WIDTH, HEIGHT, pixels, 0, WIDTH);
return image;
}

its leaving white box edgdes around image.

it’s doing what you’re telling it to do, son. that’s how computers work. it’s not magic, it’s mathematics.

1 Like

Java 2D is doing an affine transform and so will never be perspective correct. ie: all of the scaling will be linear and not z-divided.

You either have to manually transform each pixel yourself through sampling… or use a 3D library. (Note: if you are only shearing walls like that then you can get away with rendering a column at a time, transforming each by the perspective-correct scale and image column… I’ve done this. It’s not particularly fast… though faster than perspective sampling the whole image pixel-by-pixel.)

…or use a 3D editor to preprocess the image.

Edit: and yes there is vertical shearing in Java2D… look at the affine transform stuff… you should ask about that on a Java2D forum, though.

It’s an interesting question to me.

Use a 3D library like jme3, or you do all the math work yourself.

like this guy.

By the way, now I’m just learning it, trying to write a JSoftwareRenderer myself, with swing and canvas.

The more I use Java 2d, the more I miss jme3.

Yeah, I did a whole quake-style rendering engine in Java back in 1998. No hardware acceleration was really available to Java then.

http://progeeks.com/pspeed/jqmap

Edit: and by the way, that jar still runs… it’s a LOT faster now than it was back then. :slight_smile:

6 Likes

i need source code of jqmap

Thou doth not request thy goodies without a meal and a glass of wine first, good fellow. Manners maketh the man.

And you will learn far more wanting to know, than it being given on a plate.

1 Like


iam able to divide image into columns and get back them joined in final image which is this

but its giving black triangle at bottom.

any suggetion for filling this black triangle with transparent pixel at the time of merging images back.

also its resizing from the bottom not from the top

-------------------------breaking image with this code--------------------------------------

File file = new File(“f://df.jpg”); // I have bear.jpg in my working directory
FileInputStream fis = new FileInputStream(file);
BufferedImage image = ImageIO.read(fis); //reading the image file

    int rows = 1; //You should decide the values for rows and cols variables
    int cols = 80;
    int chunks = rows * cols;

    int chunkWidth = image.getWidth() / cols; // determines the chunk width and height
    int chunkHeight = image.getHeight() / rows;
    int count = 0;
    BufferedImage imgs[] = new BufferedImage[chunks]; //Image array to hold image chunks
    for (int x = 0; x < rows; x++) {
        for (int y = 0; y < cols; y++) {
            //Initialize the image array with image chunks
            imgs[count] = new BufferedImage(chunkWidth, chunkHeight, image.getType());

            // draws the image chunk
            Graphics2D gr = imgs[count++].createGraphics();
            gr.drawImage(image, 0, 0, chunkWidth, chunkHeight, chunkWidth * y, chunkHeight * x, chunkWidth * y + chunkWidth, chunkHeight * x + chunkHeight, null);
            gr.dispose();
        }
    }
    System.out.println("Splitting done");

    //writing mini images into image files
    for (int i = 0; i < imgs.length; i++) {
        ImageIO.write(imgs[i], "jpg", new File("f://shear1//img" + i + ".jpg"));
    }

------------------------------------------------resizing images with this code-------------------------------------------------------
public static void main(String[] args) throws IOException
{
for(int i=0;i<=79;i++)
{
BufferedImage image = ImageIO.read(new File(“f://shear1//img”+i+".jpg"));
BufferedImage scaled = getScaledInstance(
image, 2, 217-(i*2), RenderingHints.VALUE_INTERPOLATION_BICUBIC, true);
writeJPG(scaled, new FileOutputStream(“f://shear2//img”+i+".jpg"), 0.85f);
}
}

public static BufferedImage getScaledInstance(
    BufferedImage img, int targetWidth,
    int targetHeight, Object hint, 
    boolean higherQuality)
{
    int type =
        (img.getTransparency() == Transparency.OPAQUE)
        ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
    BufferedImage ret = (BufferedImage) img;
    int w, h;
    if (higherQuality)
    {
        // Use multi-step technique: start with original size, then
        // scale down in multiple passes with drawImage()
        // until the target size is reached
        w = img.getWidth();
        h = img.getHeight();
    }
    else
    {
        // Use one-step technique: scale directly from original
        // size to target size with a single drawImage() call
        w = targetWidth;
        h = targetHeight;
    }

    do
    {
        if (higherQuality && w > targetWidth)
        {
            w /= 2;
            if (w < targetWidth)
            {
                w = targetWidth;
            }
        }

        if (higherQuality && h > targetHeight)
        {
            h /= 2;
            if (h < targetHeight)
            {
                h = targetHeight;
            }
        }

        BufferedImage tmp = new BufferedImage(w, h, type);
        Graphics2D g2 = tmp.createGraphics();
        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
        g2.drawImage(ret, 0, 0, w, h, null);
        g2.dispose();

        ret = tmp;
    } while (w != targetWidth || h != targetHeight);

    return ret;
}

public static void writeJPG(
    BufferedImage bufferedImage,
    OutputStream outputStream,
    float quality) throws IOException
{
    Iterator<ImageWriter> iterator =
        ImageIO.getImageWritersByFormatName("jpg");
    ImageWriter imageWriter = iterator.next();
    ImageWriteParam imageWriteParam = imageWriter.getDefaultWriteParam();
    imageWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
    imageWriteParam.setCompressionQuality(quality);
    ImageOutputStream imageOutputStream =
        new MemoryCacheImageOutputStream(outputStream);
    imageWriter.setOutput(imageOutputStream);
    IIOImage iioimage = new IIOImage(bufferedImage, null, null);
    imageWriter.write(null, iioimage, imageWriteParam);
    imageOutputStream.flush();
}    

-----------------------------------merging images with this code---------------------------------------------------------

File[] imgFiles = new File[chunks];
for (int i = 0; i < chunks; i++) {
imgFiles[i] = new File(“f://shear2//img” + i + “.jpg”);
}

   //creating a bufferd image array from image files
    BufferedImage[] buffImages = new BufferedImage[chunks];
    for (int i = 0; i < chunks; i++) {
        buffImages[i] = ImageIO.read(imgFiles[i]);
    }
    type = buffImages[0].getType();
    chunkWidth = buffImages[0].getWidth();
    chunkHeight = buffImages[0].getHeight();

BufferedImage finalImg = new BufferedImage(chunkWidthcols, chunkHeightrows, type);

    int num = 0;
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            finalImg.createGraphics().drawImage(buffImages[num], chunkWidth * j, chunkHeight * i, null);
            num++;
        }
    }
  

    System.out.println("Image concatenated.....");
    ImageIO.write(finalImg, "jpeg", new File("f://finalImg.jpg"));

iam also able to remove background of image in total java

-------------------------------------------------------------with this code----------------------------------------------

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class TransparentConverter {

private static final Color backColor = new Color(0,0,0);
private static final int THRESHOLD = 35;
private static final int TRANSPARENT = 0;  // 0x00000000;

static File base  = new File("f://newimagesoutput_1374.jpg");
static File base2 = new File("f://outtrans.png");

public static void main(String[] args) throws IOException {
    System.out.println("TransparentConverter.main()");

   // for (File file : base.listFiles()) 
    {
       // System.out.println(file);
        BufferedImage initImage = ImageIO.read(base);
        int width = initImage.getWidth(null),
            height = initImage.getHeight(null);

        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics g = image.getGraphics();
        g.drawImage(initImage, 0, 0, null);

        System.out.println("before: " + image.getRGB(0, 0));
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int pixel = image.getRGB(x, y);
                Color color = new Color(pixel);

                int dr = Math.abs(color.getRed()   - backColor.getRed()),
                    dg = Math.abs(color.getGreen() - backColor.getGreen()),
                    db = Math.abs(color.getBlue()  - backColor.getBlue());

                if (dr < THRESHOLD && dg < THRESHOLD && db < THRESHOLD) {
                    image.setRGB(x, y, TRANSPARENT);
                }
            }
        }
        System.out.println("   after: " + image.getRGB(0, 0));

       File file = new File("f://outtrans1.png");
        //System.out.println("   " + file);
        ImageIO.write(image, "png", file);
    }
}

}

1 Like