WritableRaster java - java

I working on "mini photoshop" in java. I open jpg file useing this method
public BufferedImage open()
{
fc = new JFileChooser();
int ret = fc.showOpenDialog(null);
if (ret == JFileChooser.APPROVE_OPTION)
{
try {
img=ImageIO.read(fc.getSelectedFile());
img2=ImageIO.read(fc.getSelectedFile());
raster = img.getRaster();
} catch (IOException e) {
e.printStackTrace();
}
}else
img = null;
return img;
}
In this picture I make some change eg. sephia, sobel. But after this I want back to origin picture, I use for this method to do this:
public BufferedImage origin() {
raster=img.getRaster();
return img2;
}
The problem arises when I want again use sepia or any other filter because program remember earlier modification.
For example when i use sepia then back to origin and use sobel, program show me sepia+sobel, should show only sobel.

Should the below line
raster=img.getRaster();
change to
raster=img2.getRaster(); ?
public BufferedImage origin() {
raster=img.getRaster();
return img2;
}

Related

Forcing ".png" in JFileChooser Save Dialog

I'm trying to get an automatic .png behind the Filename in the JFileChooser.
How can I accomplish that?
public class Capture {
public static BufferedImage getScreenShot(Component component) {
BufferedImage image = new BufferedImage(component.getWidth(), component.getHeight(), BufferedImage.TYPE_INT_RGB);
component.paint(image.getGraphics());
return image;
}
public static void getSaveSnapShot(Component component, String fileName) throws Exception {
BufferedImage img = getScreenShot(component);
JFileChooser jfc = new JFileChooser();
jfc.addChoosableFileFilter(new FileNameExtensionFilter("Image files",new String[] { "png" }));
int retVal = jfc.showSaveDialog(null);
if(retVal==JFileChooser.APPROVE_OPTION) {
File f = jfc.getSelectedFile();
String test = f.getAbsolutePath();
ImageIO.write(img,"png",new File(test));
}
}
}
Just check if the path ends with png. If not add it:
...
String test = f.getAbsolutePath();
if (!test.endsWith(".png")) {
test = test + ".png";
}
...
You also have the option to add a filter to allow only some kind of files.
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("Images", "jpg", "png", "gif", "bmp"));
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("*.pdf", "pdf"));
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("*.txt", "txt"));
That can help if you want to be sure to not have corrupted file when adding manually their type.

save zoom image level to file

Let's say that I want to load an shp file, do my stuff on it and save the map as an image.
In order to save an image I am using:
public void saveImage(final MapContent map, final String file, final int imageWidth) {
GTRenderer renderer = new StreamingRenderer();
renderer.setMapContent(map);
Rectangle imageBounds = null;
ReferencedEnvelope mapBounds = null;
try {
mapBounds = map.getMaxBounds();
double heightToWidth = mapBounds.getSpan(1) / mapBounds.getSpan(0);
imageBounds = new Rectangle(0, 0, imageWidth, (int) Math.round(imageWidth * heightToWidth));
} catch (Exception e) {
// Failed to access map layers
throw new RuntimeException(e);
}
BufferedImage image = new BufferedImage(imageBounds.width, imageBounds.height, BufferedImage.TYPE_INT_RGB);
Graphics2D gr = image.createGraphics();
gr.setPaint(Color.WHITE);
gr.fill(imageBounds);
try {
renderer.paint(gr, imageBounds, mapBounds);
File fileToSave = new File(file);
ImageIO.write(image, "png", fileToSave);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
But, let's say I am doing something like this:
...
MapContent map = new MapContent();
map.setTitle("TEST");
map.addLayer(layer);
map.addLayer(shpLayer);
// zoom into the line
MapViewport viewport = new MapViewport(featureCollection.getBounds());
map.setViewport(viewport);
saveImage(map, "/tmp/img.png", 800);
1) The problem is that the zoom level isn't saved on the image file.Is there a way to save it?
2) When I am doing MapViewport(featureCollection.getBounds()); is there a way to extend a little bit the boundaries in order to have a better visual representation?
...
The reason that you aren't saving the map at the current zoom level is that in your saveImage method you have the line:
mapBounds = map.getMaxBounds();
which always uses the full extent of the map, you can change this to
mapBounds = map.getViewport().getBounds();
You can expand a bounding box by something like:
ReferencedEnvelope bounds = featureCollection.getBounds();
double delta = bounds.getWidth()/20.0; //5% on each side
bounds.expandBy(delta );
MapViewport viewport = new MapViewport(bounds);
map.setViewport(viewport );
A quicker (and easier) way to save a map from the GUI is to use a method like this which just saves exactly what is on the screen:
public void drawMapToImage(File outputFile, String outputType,
JMapPane mapPane) {
ImageOutputStream outputImageFile = null;
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(outputFile);
outputImageFile = ImageIO.createImageOutputStream(fileOutputStream);
RenderedImage bufferedImage = mapPane.getBaseImage();
ImageIO.write(bufferedImage, outputType, outputImageFile);
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
if (outputImageFile != null) {
outputImageFile.flush();
outputImageFile.close();
fileOutputStream.flush();
fileOutputStream.close();
}
} catch (IOException e) {// don't care now
}
}
}

Set clipboard to transparent image

I am creating a program that needs to copy an image to clipboard.
The problem is that the image has a transparent background and, whenever I copy it, the image comes out with a black background instead of transparent.
I tried lots of things since 2 days ago but none worked.
The class imageSelection is based on http://www.java2s.com/Tutorial/Java/0120__Development/SettinganimageontheclipboardwithacustomTransferableobjecttoholdtheimage.htm
package Package1;
import java.awt.Image;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
/** Transferable image */
public class imageSelection implements Transferable {
private Image image;
/** Creates a "transferable image" */
public imageSelection(Image image) {
this.image = image;
}
public DataFlavor[] getTransferDataFlavors() {
DataFlavor[] transferData = new DataFlavor[] { DataFlavor.imageFlavor }; // <--- Works but gives me a black background instead of transparent
/* I tried this (based on https://stackoverflow.com/questions/15977001/clipboard-copy-from-outlook-always-has-black-background-set-when-retrieved-as-im) but wasn't able to achieve any good result with it.
DataFlavor transferData = null;
try {
transferData = new DataFlavor(Image.class, null); // <---- How to get an object of the type DataFlavor[] from this ( DataFlavor("image/x-emf") is of the type DataFlavor, not DataFlavor[] )
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
error.displayError(e.getStackTrace(), "Error creating DataFlavor (mime type: image/x-emf)");
}
return new DataFlavor[] { transferData }
*/
return transferData;
}
public boolean isDataFlavorSupported(DataFlavor flavor) {
return DataFlavor.imageFlavor.equals(flavor);
}
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
if (!DataFlavor.imageFlavor.equals(flavor)) {
throw new UnsupportedFlavorException(flavor);
}
return image;
}
}
Call:
imageSelection imgSel = new imageSelection(new ImageIcon(emojiLocation).getImage());
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(imgSel, null);
Thanks
I am testing the contents by pasting it into Discord (chat app and it does support transparency, I made sure of that).
I am using jdk1.8.0_131.
I am using Windows 10 64bits fully updated.
If needed, full source code here: https://github.com/KingOffNothing/EmojiMenu-for-discord/tree/master/src/Package1
What the program does is change the clipboard to a selected image and then a program written in AHK will simulate the key press ctrl+v that pastes the image.
I was not able to exactly fix the transparency issue but was able to do a workaround (change transparent pixels to match the background's color)
private static BufferedImage fixTransparency(BufferedImage image) {
int width = image.getWidth();
int height = image.getHeight();
Color discordChatColor = new Color(54,57,62, 255);
for (int xx = 0; xx < width; xx++) {
for (int yy = 0; yy < height; yy++) {
Color originalColor = new Color(image.getRGB(xx, yy), true);
if (originalColor.getAlpha() == 0) {
image.setRGB(xx, yy, discordChatColor.getRGB());
}
}
}
return image;
}

ANDROID ZXING: Saving a photo in onPreviewFrame saves a photo every frame. How to only save a single photo upon scan?

For the last few weeks I have been attempting to alter Zxing to take a photo immediately upon scan. Thanks to help I am at a point where I can be consistently saving an image from the onPreviewFrame class within PreviewCallback.java
The code I use within the onPreviewMethod method shall follow, and then a short rundown of how my app works.
public void onPreviewFrame(byte[] data, Camera camera) {
Point cameraResolution = configManager.getCameraResolution();
Handler thePreviewHandler = previewHandler;
android.hardware.Camera.Parameters parameters = camera.getParameters();
android.hardware.Camera.Size size = parameters.getPreviewSize();
int height = size.height;
int width = size.width;
System.out.println("HEIGHT IS" + height);
System.out.println("WIDTH IS" + width);
if (cameraResolution != null && thePreviewHandler != null) {
YuvImage im = new YuvImage(data, ImageFormat.NV21, width,
height, null);
Rect r = new Rect(0, 0, width, height);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
im.compressToJpeg(r, 50, baos);
try {
FileOutputStream output = new FileOutputStream("/sdcard/test_jpg.jpg");
output.write(baos.toByteArray());
output.flush();
output.close();
System.out.println("Attempting to save file");
System.out.println(data);
} catch (FileNotFoundException e) {
System.out.println("Saving to file failed");
} catch (IOException e) {
System.out.println("Saving to file failed");
}
Message message = thePreviewHandler.obtainMessage(previewMessage, cameraResolution.x,
cameraResolution.y, data);
message.sendToTarget();
previewHandler = null;
} else {
Log.d(TAG, "Got preview callback, but no handler or resolution available");
}}
My application centers around its own GUI and functionality, but can engage Zxing via intent (Zxing is built into the apps build path, yes this is bad as it can intefere if Zxing is already installed). Once Zxing has scanned a QR code, the information encoded on it is returned to my app and stored, and then after a short delay Zxing is automatically re-initiated.
My current code saves an image every frame whilst Zxing is running, the functionality I would like is to have only the frame on scan be saved. Although Zxing stops saving images in the short window where my app takes over again, Zxing is quickly re-initialized however and I may not have time to manipulate the data. A possible workaround however is quickly renaming the saved file so that Zxing doesn't start overwriting it and manipulation can be performed in the background. Nevertheless, saving an image every frame is a waste of resources and less than preferable.
How do I only save an image upon scan?
Thanks in advance.
Updated to show found instances of multiFormatReader as requested:
private final CaptureActivity activity;
private final MultiFormatReader multiFormatReader;
private boolean running = true;
DecodeHandler(CaptureActivity activity, Map<DecodeHintType,Object> hints) {
multiFormatReader = new MultiFormatReader();
multiFormatReader.setHints(hints);
this.activity = activity;
}
#Override
public void handleMessage(Message message) {
if (!running) {
return;
}
if (message.what == R.id.decode) {
decode((byte[]) message.obj, message.arg1, message.arg2);
} else if (message.what == R.id.quit) {
running = false;
Looper.myLooper().quit();
}}
private void decode(byte[] data, int width, int height) {
long start = System.currentTimeMillis();
Result rawResult = null;
PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(data, width, height);
if (source != null) {
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
//here?
try {
rawResult = multiFormatReader.decodeWithState(bitmap);
} catch (ReaderException re) {
// continue
} finally {
multiFormatReader.reset();
}
}
ZXing detects every received frame until finds out correct information. The image saving point is when ZXing returns a string which is not null. In addition, you can save file with different name "timestamp + .jpg", in case previous file will be overwritten.

How to rescale and save an BufferedImage

I got a BufferedImage and want to rescale it before saving it as an jpg/png.
I got the following code:
private BufferedImage rescaleTo(BufferedImage img,int minWidth,int minHeight) {
BufferedImage buf = toBufferedImage(img.getScaledInstance(minWidth, minHeight, Image.SCALE_DEFAULT));
BufferedImage ret = new BufferedImage(buf.getWidth(null),buf.getHeight(null),BufferedImage.TYPE_INT_ARGB);
return ret;
}
public BufferedImage toBufferedImage(Image img) {
BufferedImage ret = new BufferedImage(img.getWidth(null),img.getHeight(null),BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = ret.createGraphics();
g2.drawImage(img,0,0,null);
return ret;
}
public String saveTo(BufferedImage image,String URI) throws UtilityException {
try {
if(image == null)
System.out.println("dododod");
ImageIO.write(image, _type, new File(URI));
} catch (IOException e) {
throw new UtilityException(e.getLocalizedMessage());
}
return URI;
}
But as an result I just get a black picture. It must have to do with the rescaling as when I skip it I can save the expected picture.
As a test, set _type="png" and also use file extension .png when you make the call to ImageIO.write(image, _type, new File(URI));. I had issues like you describe and I started writing type PNG and all works fine. Unfortunately, I never went back to debug why I could not write type JPG, GIF etc.

Categories