Crop youtube type image in Java - java

I have a difficulty cropping the image in Java. I have image that has black lines up and down. The image looks like this :
Image
I want to remove the black frame from the image and the width to remain the same. Please send me some solution to my problem. I tried something like this, but it crops only the bottom of the image.
BufferedImage originalImg = ImageIO.read(
new File(imageLocation));
// Fetching and printing alongside the
// dimensions of original image using getWidth()
// and getHeight() methods
System.out.println("Original Image Dimension: "
+ originalImg.getWidth()
+ "x"
+ originalImg.getHeight());
// Creating a subimage of given dimensions
BufferedImage SubImg
= originalImg.getSubimage(0,0,originalImg.getWidth(), 217);
// Printing Dimensions of new image created
System.out.println("Cropped Image Dimension: "
+ SubImg.getWidth() + "x"
+ SubImg.getHeight());
// Creating new file for cropped image by
// creating an object of File class
File outputfile
= new File(defaultPath+"crop_Image.jpg");
// // Writing image in new file created
ImageIO.write(SubImg, "jpg", outputfile);
// Display message on console representing
// // proper execution of program
System.out.println(
"Cropped Image created successfully");
}

You can use getRGB and setRGB to copy image area to the new image.
import java.awt.image.BufferedImage;
public class ImageUtil {
public static BufferedImage crop(BufferedImage image, int top, int right, int bottom, int left) {
int newWidth = image.getWidth() - left - right;
int newHeight = image.getHeight() - top - bottom;
int[] rgb = image.getRGB(left, top, newWidth, newHeight, null, 0, newWidth);
BufferedImage newImage = new BufferedImage(newHeight, newHeight, BufferedImage.TYPE_INT_ARGB);
newImage.setRGB(0, 0, newWidth, newHeight, rgb, 0, newWidth);
return newImage;
}
}

Related

How to crop image in java?

I'm using java to crop image when upload file, I set value and to try to crop but is not get correct size of image as I expected
This my code: (updated)
private BufferedImage cropImageSquare(byte[] image) throws IOException {
InputStream in = new ByteArrayInputStream(image);
BufferedImage originalImage = ImageIO.read(in);
System.out.println("Original Image Dimension: "+originalImage.getWidth()+"x"+originalImage.getHeight());
BufferedImage croppedImage = originalImage.getSubimage(300, 150, 500, 500);
System.out.println("Cropped Image Dimension: "+croppedImage.getWidth()+"x"+croppedImage.getHeight());
return croppedImage;
}
my photo:
I want to crop image as above image (red line) but my code is seem incorrect.
How to crop image as expect?
I want to crop image as above image (red line) but my code is seem incorrect.
So, your input image is 1024x811 and your "target" image is 928x690, which is roughly 0.906x0.8509 reduction/difference - so the real question is ... which one of those is the right value?
Through my testing, based on this image, 0.8509 produces the best result
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Test {
public static void main(String[] args) throws IOException {
BufferedImage crop = new Test().crop(0.8509);
System.out.println(crop.getWidth() + "x" + crop.getHeight());
ImageIO.write(crop, "jpg", new File("Square.jpg"));
}
public BufferedImage crop(double amount) throws IOException {
BufferedImage originalImage = ImageIO.read(Test.class.getResource("Cat.jpg"));
int height = originalImage.getHeight();
int width = originalImage.getWidth();
int targetWidth = (int)(width * amount);
int targetHeight = (int)(height * amount);
// Coordinates of the image's middle
int xc = (width - targetWidth) / 2;
int yc = (height - targetHeight) / 2;
// Crop
BufferedImage croppedImage = originalImage.getSubimage(
xc,
yc,
targetWidth, // widht
targetHeight // height
);
return croppedImage;
}
}
Now, this doesn't do any checks (xc + targetWidth > imageWidth), but I'm sure you can fill that out
Code is working fine for me.
public class Test {
public static void main( String[] args ) throws IllegalAccessException, InstantiationException {
try{
BufferedImage image = ImageIO.read(new File("C:\\Users\\guptab\\Pictures\\American.png"));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, "png", baos);
byte[] res=baos.toByteArray();
image = new Test().cropImageSquare(res);
}
catch(Exception e) {
e.printStackTrace();
System.out.println("Error");
}
}
private BufferedImage cropImageSquare(byte[] image) throws IOException {
InputStream in = new ByteArrayInputStream(image);
BufferedImage originalImage = ImageIO.read(in);
System.out.println("Original Image Dimension: "+originalImage.getWidth()+"x"+originalImage.getHeight());
BufferedImage croppedImage = originalImage.getSubimage(300, 150, 300, 600);
System.out.println("Cropped Image Dimension: "+croppedImage.getWidth()+"x"+croppedImage.getHeight());
return croppedImage;
}
}
Output is:
Original Image Dimension: 1279x1023
Cropped Image Dimension: 300x600
Definition of getSubImage method:
BufferedImage java.awt.image.BufferedImage.getSubimage(int x, int y, int w, int h)
Returns a subimage defined by a specified rectangular region. The returned BufferedImage shares the same data array as the original image.
Parameters:x the X coordinate of the upper-left corner of the specified rectangular regiony the Y coordinate of the upper-left corner of the specified rectangular regionw the width of the specified rectangular regionh the height of the specified rectangular regionReturns:a BufferedImage that is the subimage of this BufferedImage.
So int x and int y (First two Parameters are coordinates of image, not dimensions), only int w, int h (last two parameters) are dimensions of the image which is working fine.

Image Thinning using JAVA

I have written some code in java to convert a colored image into black and white image and then tried to perform thinning on that gray-scale image. Black and white conversion is done successfully, but image thinning is still not giving correct output. Kindly help me in fixing my problem. My code is as follows:
//colored image to black and white conversion; black and white image to thinned image.
public static void main(String[] args)
{
try
{
//colored image path
BufferedImage colored_image = ImageIO.read(new File("D:\\logo.jpg"));
//getting width and height of image
double image_width = colored_image.getWidth();
double image_height = colored_image.getHeight();
BufferedImage img = colored_image;
//drawing a new image
BufferedImage bimg = new BufferedImage((int)image_width, (int)image_height, BufferedImage.TYPE_BYTE_GRAY);
Graphics2D gg = bimg.createGraphics();
gg.drawImage(img, 0, 0, img.getWidth(null), img.getHeight(null), null);
//saving black and white image onto drive
String temp = "logo in blackAndwhite.jpeg";
File fi = new File("D:\\" + temp);
ImageIO.write(bimg, "jpg", fi);
//thinning by resizing gray scale image to desired eight and width
BufferedImage bimg2 = new BufferedImage((int)image_width, (int)image_height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = bimg2.createGraphics();
// Perform your drawing here
g2.setColor(Color.BLACK);
g2.drawLine(0, 0, 200, 200);
//saving thinned image onto drive
String temp2 = "logo thinned.jpeg";
File fi2 = new File("D:\\" + temp2);
ImageIO.write(bimg2, "jpg", fi2);
//g2.dispose();
}
catch (Exception e)
{
System.out.println(e);
}
}
}
Check java.awt.geom.AffineTransform
AffineTransform tx = new AffineTransform();
tx.scale(20, 30);
AffineTransformOp afop = new AffineTransformOp(tx,
AffineTransformOp.TYPE_BILINEAR);
BufferedImage bi = afop.filter(ogininal, null);
Icon icon = new ImageIcon(bi); //here icon will be your thumbnail image

Rotate Buffered Image (diagonal Text)

(Sorry for the links, I'm new and I cannot post images)
I want to accomplish the following : create a table with the legends on the top, and in a diagonal way.
but I'm having some problems, I have the following image, and I'm trying to rotate it 45º (the result it's at the right),
Here is my code:
//just some labels
ArrayList<String> labels = new ArrayList<String>();
labels.add("Juan");
labels.add("QWERTYYY");
labels.add("ANA");
// margin
int margin=3;
//diagonal = 45º
// value to shift each label
int diagonalShift = (int)(cellSizeWidth / Math.sqrt(2d));
// height, width represent the size of the final image
// heightSub, widthSub represent the size of the image to be rotated taking into account the shift for each label
int widthSub = height + (diagonalShift * labels.size());
int heightSub = width;
// image to Display
BufferedImage image = new BufferedImage(height, width, BufferedImage.TYPE_INT_RGB);
Graphics2D imageGraphics = (Graphics2D) image.getGraphics();
// tempImage: subImage to rotate and place in image
BufferedImage tempImage = new BufferedImage(widthSub, heightSub, BufferedImage.TYPE_INT_RGB);
Graphics2D tempImageGraphics = (Graphics2D) tempImage.getGraphics();
tempImageGraphics.setColor(Color.BLUE);
tempImageGraphics.drawRect(0, 0, widthSub-1, heightSub-1);
// I'd like to use antialias, but it's giving bad results
// tempImageGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
// drawing labels
// as we're designing a table cellSizeWidth and CellSizeHeight represent the dimensions for each cell
tempImageGraphics.setColor(Color.WHITE);
for (int i = 0; i < labels.size(); i++) {
String label = labels.get(i);
tempImageGraphics.drawString(label,
margin + (i * diagonalShift),
(int) (i * cellSizeWidth) + fontSize + centerDistance);
}
I tried the following:
//rotating
AffineTransform fontAfineTransform = new AffineTransform();
// fontAfineTransform.rotate(verticalTextDirection.rotationAngle());
which gives as result the image at the right in the second Image 2
so I need to apply a translation to get it to the right position
// Math.sqrt(2d) because I'm working with 45º and the height becomes the hypotenuse
// fontAfineTransform.translate(-height/Math.sqrt(2d),height/Math.sqrt(2d));
//drawing into image
imageGraphics.drawImage(tempImage, fontAfineTransform, null);
can someone please explain how the affineTransform works, or how can I get the text to be in a diagonal way.
Thanks

Image Processing in Java

I want to extract the pixel values of the jpeg image using the JAVA language, and need to store it in array(bufferdArray) for further manipulation. So how i can extract the pixel values from jpeg image format?
Have a look at BufferedImage.getRGB().
Here is a stripped-down instructional example of how to pull apart an image to do a conditional check/modify on the pixels. Add error/exception handling as necessary.
public static BufferedImage exampleForSO(BufferedImage image) {
BufferedImage imageIn = image;
BufferedImage imageOut =
new BufferedImage(imageIn.getWidth(), imageIn.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
int width = imageIn.getWidth();
int height = imageIn.getHeight();
int[] imageInPixels = imageIn.getRGB(0, 0, width, height, null, 0, width);
int[] imageOutPixels = new int[imageInPixels.length];
for (int i = 0; i < imageInPixels.length; i++) {
int inR = (imageInPixels[i] & 0x00FF0000) >> 16;
int inG = (imageInPixels[i] & 0x0000FF00) >> 8;
int inB = (imageInPixels[i] & 0x000000FF) >> 0;
if ( conditionChecker_inRinGinB ){
// modify
} else {
// don't modify
}
}
imageOut.setRGB(0, 0, width, height, imageOutPixels, 0, width);
return imageOut;
}
The easiest way to get a JPEG into a java-readable object is the following:
BufferedImage image = ImageIO.read(new File("MyJPEG.jpg"));
BufferedImage provides methods for getting RGB values at exact pixel locations in the image (X-Y integer coordinates), so it'd be up to you to figure out how you want to store that in a single-dimensional array, but that's the gist of it.
There is a way of taking a buffered image and converting it into an integer array, where each integer in the array represents the rgb value of a pixel in the image.
int[] pixels = ((DataBufferInt)image.getRaster().grtDataBuffer()).getData();
The interesting thing is, when an element in the integer array is edited, the corresponding pixel in the image is as well.
In order to find a pixel in the array from a set of x and y coordinates, you would use this method.
public void setPixel(int x, int y ,int rgb){
pixels[y * image.getWidth() + x] = rgb;
}
Even with the multiplication and addition of coordinates, it is still faster than using the setRGB() method in the BufferedImage class.
EDIT:
Also keep in mind, the image needs type needs to be that of TYPE_INT_RGB, and isn't by default. It can be converted by creating a new image of the same dimensions, and of the type of TYPE_INT_RGB. Then using the graphics object of the new image to draw the original image to the new one.
public BufferedImage toIntRGB(BufferedImage image){
if(image.getType() == BufferedImage.TYPE_INT_RGB)
return image;
BufferedImage newImage = new BufferedImage(image.getWidth(), image.getHeight, BufferedImage.TYPE_INT_RGB);
newImage.getGraphics().drawImage(image, 0, 0, null);
return newImage;
}

How to resize JLabel ImageIcon?

I'm making a Java Swing application that has the following layout (MigLayout):
[icon][icon][icon][....]
where icon = jlabel and the user can add more icons
When the user adds or removes icons, the others should shrink or grow.
My question is really straightforward: I have a JLabel which contains an ImageIcon; how can I resize this icon?
Try this :
ImageIcon imageIcon = new ImageIcon("./img/imageName.png"); // load the image to a imageIcon
Image image = imageIcon.getImage(); // transform it
Image newimg = image.getScaledInstance(120, 120, java.awt.Image.SCALE_SMOOTH); // scale it the smooth way
imageIcon = new ImageIcon(newimg); // transform it back
(found it here)
Resizing the icon is not straightforward. You need to use Java's graphics 2D to scale the image. The first parameter is a Image class which you can easily get from ImageIcon class. You can use ImageIcon class to load your image file and then simply call getter method to get the image.
private Image getScaledImage(Image srcImg, int w, int h){
BufferedImage resizedImg = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = resizedImg.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(srcImg, 0, 0, w, h, null);
g2.dispose();
return resizedImg;
}
And what about it?:
ImageIcon imageIcon = new ImageIcon(new ImageIcon("icon.png").getImage().getScaledInstance(20, 20, Image.SCALE_DEFAULT));
label.setIcon(imageIcon);
From: Resize a picture to fit a JLabel
This will keep the right aspect ratio.
public ImageIcon scaleImage(ImageIcon icon, int w, int h)
{
int nw = icon.getIconWidth();
int nh = icon.getIconHeight();
if(icon.getIconWidth() > w)
{
nw = w;
nh = (nw * icon.getIconHeight()) / icon.getIconWidth();
}
if(nh > h)
{
nh = h;
nw = (icon.getIconWidth() * nh) / icon.getIconHeight();
}
return new ImageIcon(icon.getImage().getScaledInstance(nw, nh, Image.SCALE_DEFAULT));
}
One (quick & dirty) way to resize images it to use HTML & specify the new size in the image element. This even works for animated images with transparency.
I agree this code works, to size an ImageIcon from a file for display while keeping the aspect ratio I have used the below.
/*
* source File of image, maxHeight pixels of height available, maxWidth pixels of width available
* #return an ImageIcon for adding to a label
*/
public ImageIcon rescaleImage(File source,int maxHeight, int maxWidth)
{
int newHeight = 0, newWidth = 0; // Variables for the new height and width
int priorHeight = 0, priorWidth = 0;
BufferedImage image = null;
ImageIcon sizeImage;
try {
image = ImageIO.read(source); // get the image
} catch (Exception e) {
e.printStackTrace();
System.out.println("Picture upload attempted & failed");
}
sizeImage = new ImageIcon(image);
if(sizeImage != null)
{
priorHeight = sizeImage.getIconHeight();
priorWidth = sizeImage.getIconWidth();
}
// Calculate the correct new height and width
if((float)priorHeight/(float)priorWidth > (float)maxHeight/(float)maxWidth)
{
newHeight = maxHeight;
newWidth = (int)(((float)priorWidth/(float)priorHeight)*(float)newHeight);
}
else
{
newWidth = maxWidth;
newHeight = (int)(((float)priorHeight/(float)priorWidth)*(float)newWidth);
}
// Resize the image
// 1. Create a new Buffered Image and Graphic2D object
BufferedImage resizedImg = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = resizedImg.createGraphics();
// 2. Use the Graphic object to draw a new image to the image in the buffer
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(image, 0, 0, newWidth, newHeight, null);
g2.dispose();
// 3. Convert the buffered image into an ImageIcon for return
return (new ImageIcon(resizedImg));
}
I found that there is a minor edit to this fix from trolologuy on the last line of code, you will need to implement a new ImageIcon to get the code to compile properly (Yes I know this is 10 years ago). I found this to be an easy fix for a one off issue, but Suken Shah and Mr. Polywhirl have a better fix overall.
ImageIcon imageIcon = new ImageIcon("./img/imageName.png"); // assign image to a new ImageIcon
Image image = imageIcon.getImage(); // transform it
Image newimg = image.getScaledInstance(120, 120, java.awt.Image.SCALE_SMOOTH); // scale it smoothly
ImageIcon newImageIcon = new ImageIcon(newimg); // assign to a new ImageIcon instance

Categories