imagick convert png to jpg in java with im4java - java

I need to convert from PNG to JPG.
However, iMagick adds a black background to it.
I saw this question which is for PHP, and tried to write the same for java like this:
// create the a jpg image
ConvertCmd cmd = new ConvertCmd();
// create the operation, add images and operators/options
IMOperation op = new IMOperation();
op.addImage(brandingURL);
op.format("JPEG");
op.composite();
op.background("white");
op.addImage(imageLocation);
//op.transparent();
// execute the operation
cmd.run(op);
But still, the image comes out with a black background.
What am I missing?

I had to write the code like this:
Info imageInfo = new Info(brandingURL, true);
IMOperation op = new IMOperation();
op.addImage(brandingURL);
op.size(imageInfo.getImageWidth(), imageInfo.getImageHeight());
op.addImage("xc:white", "c://write//test.jpeg");
op.addImage("c://write//test.jpeg");
CompositeCmd composite = new CompositeCmd();
composite.run(op);

The call to background should not be necessary. Accroding to the documentation, the default background is white, which suugests to me that maybe one of your pictures has a black background that overwrites/blocks the default (maybe the the one at brandingURL?).
Quote from the above linked documentation for ImageMagick:
-background color
Set the background color.
The color is specified using the format described under the -fill option. The default background color (if none is specified or found in the image) is white.
If you are using it precisely because one of the images does specify a (black) background, I suggest you move the background call to either before adding that picture or to the end of the operation (Not sure how ImageMagick operates wrt to this)

Related

Does an Android Bitmap from BitmapFactory decode() contain transparent information?

I have ported a Java implementation of AnimateGIFWriter to Android here. It works fine except I don't get the transparency. I tried to pass an Options to the decode() method like this:
Options opts = new Options();
opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeStream(fin, null, opts);
After reading the input image into a Bitmap, I will grab the data as an int array through Bitmap.getPixels() and auto-detect the transparency from the alpha value. But this doesn't work - the resulting animated GIF is not transparent (The input images are all transparent and my code is supposed to keep them through auto-transparency detect. This works for desktop application).
I am not quite familiar with Android related stuff. My question is given the above configuration, will BitmapFactory.decode() keep the transparency information of the input image?
Update: I found out for images support full alpha transparency like PNG images, it does keep the transparency information. But for single color transparency images like GIF, it seems not. This needs further confirmation.
My question is given the above configuration, will BitmapFactory.decode() keep the transparency information of the input image?
Yes, transparency/alpha should be loaded into that bitmap.
To verify this, you could try fetching the value of a single pixel -- maybe (0,0) -- and printing it to the log.
I don't have the time (or desire) to get into your full 1600 lines of code, but I would be suspicious of this part in the writeFrame method:
if(frame.getTransparencyFlag() == GIFFrame.TRANSPARENCY_INDEX_SET && frame.getTransparentColor() != -1) {

How To Reset or Clear or Undo DrawLine in Java

Please consider the following sample image :
All the objects (rectangles, shapes, texts, etc..) are written in BufferedImage. My questions is, after I write a graphics.drawline(..) on top of them, how to undo, or reset or clear the line(s) I created. Even if I re-execute the initialization of my graph, the lines that I drew are still there.
I can still capture the coordinates of the lines. If it is a plain background I can just re-draw it with the same background. But, in this case, this wont work.
There is no way to undo things that you do with Graphics. But there are other things you can do instead with which you can get your image back.
Keep a copy of image before you do anything which you might want to undo.
And redraw it when required.
Keep a clip image of the area of image before you do anything which you might want to undo. And redraw that area when required.
To keep a Stack of these images of limited size will be a good idea to undo back in series. Don't make the stack size too big because it will consume your heap memory
I found an answer using deep copy :)
So, first, I deep copied the original or default image. Then, If I write something on the original I overwrite it with the back up copied (deep copied again)..
static BufferedImage deepCopy(BufferedImage bi) {
ColorModel cm = bi.getColorModel();
boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
WritableRaster raster = bi.copyData(null);
return new BufferedImage(cm, raster, isAlphaPremultiplied, null);
}
Complete code can be found here..

Toolkit.getDefaultToolkit().createImage() vs ImageIO.read()

I'm creating a UI using Swing and I want to display an image in a JLabel. The code I use is the following:
JLabel label = new JLabel(new ImageIcon(ImageIO.read(new File("img.jpg"))));
This works fine if I use png images but when it comes to jpg (only some of them), I get a redish image (a different one than the one I see in Paint.NET).
The image I used is this one: img.jpg
So I tried (as an alternative):
Toolkit.getDefaultToolkit().createImage(new File("img.jpg").getAbsolutePath());
Does anyone have an idea of why this happening? Is it a special JPEG format which is not supported?
I've read on this forum that most people recommend to use ImageIO (here for example). Why?
Thanks a lot
As discussed here, your JPEG image may contain spurious transparency information. One simple expedient is to render the image in a buffer having a compatible color model, as shown here.
It looks like you have found a bug in ImageIO.read... (I can reproduce the red tint, and it is definitely not how it should look like).
You can try to
save the JPEG files with other settings
open/re-save the file with other programs (hoping to get a more common JPEG-encoding)
or use the Toolkit method (if you don't control the images).
The only problem with the Toolkit method is that the getImage() method returns immediately after it is invoked and the loading is happening on a background thread, so you cannot start working with the Image object immediately.

How to work with BufferedImage and YCbCr colorspace?

I need to translate colors in bitmap loaded to BufferedImage from RGB to YCbCr (luminance and 2 channels chrominance) and back after process.
I made it with functions used like rgb2ycbcr() in main method for each pixel, but it isn't so smart solution. I should use ColorSpace and ColorModel classes to get BufferedImage with correct color space. It would be more flexible method, but I don't know how to do that.
I'm lost and I need some tips. Can somebody help me?
As I understood your question, you want to do the following:
Load RGB image -> process YCbCr image -> Use RGB image again
And you want us to help you, to make this process as seamless as possible. First and foremost you want us to give you a simple way to avoid the -> (converting) parts.
Well I looked into the BufferedImage documentation. It seems, as if there doesn't exist a way to change the ColorSpace of an once created BufferedImage.
You could create a new BufferedImage with an YCbCr color space for that you can use the predefined ICC_ColorSpace. Then you copy the data from your old image possibly via ColorSpace.fromRGB to the YCbCr color space, do the image processing and then convert again via ColorSpace.toRGB. This method requires you to fully convert the image before and after processing via existing methods. Furthermore you have to know, how ICC_ColorSpace converts your image to YCbCr color space. Otherwise you can't know, which array indices corresponds to the same pixel.
If you just want to create a wrapper around the RGB-BufferedImage that lets you manipulate this image, as if it was an YCbCr image, that isn't possible with BufferedImage.
EDIT:
To convert the color space of a BufferedImage use ColorConvertOp. The code would look something like this:
ColorConvertOp cco = new ColorConvertOp(new YCbCrColorSpace(), null);
BufferedImage ycbcrImage = cco.filter( oldRGBImage, null );
This requires you to either write your own ColorSpace class or you could download and use the classes mentioned here. If you just want to load a JPEG image you should use the predefined classes.

How do I create an alphablending BufferedImage using J2ME (CDC/PP 1.1)

I have a BufferedImage created using
new BufferedImage(wid,hgt,BufferedImage.TYPE_INT_ARGB);
to which I assemble a wallpaper using multiple other images. It works fine in Jave SE, but when I tried to run the code on a J9 CDC/PP platform I discovered that the Personal Profile BufferedImage has no constructors!
Can anyone point me to how I can construct an alpha-channel supporting image using CDC 1.0 and Personal Profile 1.1?
Edit: For now I have created fallback code which handles NoSuchMethodError (et al.) and then simply creates an image with GraphicsConfiguration.createCompatibleImage(int,int). It might be that that creates an alpha-blending image, but it will be a few weeks before I can specifically test that due to other priorities (testing on handhelds is not my direct responsibility, so it's out of my hands).
If I find a better answer, I will post it as an answer to this; in the meantime, if someone else beats me to it, be assured I will accept your answer if it works, and the answer will be of interest to me for the foreseeable future (I expect to still need an answer in 2-5 years).
The Image class (javax.microedition.lcdui.Image
) contains a method getRGB(...) which parses the Image into an array of RGB+Alpha values for each pixel in the image. Once you have the image in that format, its easy to tweak the alpha values to increase their transparency before you layer the images. This is really the only dynamic way I've seen to edit the transparency of an image in J2ME.
to get the alpha (transparency) value out of the rgba array you have to use bit-shifting like this:
int origAlpha = (rgba[j] >> 24);
and then to change the alpha (transparency) value to something different (without changing the color at that pixel), you can use bitshifting to insert a different transparency level.
int newAlpha = 0x33; // or use whatever 0-255 value you want, with 255=opaque, 0=transparent
rgba[j] = (rgba[j] & 0x00ffffff);
rgba[j] = (rgba[j] | (newAlpha << 24));
Then there is a createImage(...) method in Image that takes a byte-array of image data as a parameter, that can be used to create a new image out of your modified pixel data array.
Also helpful, SonyEricsson's developer website also has a tutorial with sample code called "Fade in and out images in MIDP 2.0" which explains "how to change the alpha value of an image to make it appear blended" which is essentially alpha-blending.

Categories