# 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.

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);

``````    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 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)
{
// 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++) {
}
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);
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