Create image from scratch with JMagick - java

I am using Java port of ImageMagick called JMagick .I need to be able to create a new image and write an arbitrary text chunk into it.The docs are very poor and what I managed to get so far is to write text into the image which comes from IO.Also , in all the examples I have found it seems like the very first operation ,before writing new image data , is always loading of an existing image into ImageInfo instance.How do I create an image from scratch with JMagick and then write a text into it?
Here is what I do now :
try {
ImageInfo info = new ImageInfo();
info.setSize("512x512");
info.setUnits(ResolutionType.PixelsPerInchResolution);
info.setColorspace(ColorspaceType.RGBColorspace);
info.setBorderColor(PixelPacket.queryColorDatabase("red"));
info.setDepth(8);
BufferedImage img = new BufferedImage(512,512,BufferedImage.TYPE_4BYTE_ABGR);
byte[] imageBytes = ((DataBufferByte) img.getData().getDataBuffer()).getData();
MagickImage mimage = new MagickImage(info,imageBytes);
DrawInfo aInfo = new DrawInfo(info);
aInfo.setFill(PixelPacket.queryColorDatabase("green"));
aInfo.setUnderColor(PixelPacket.queryColorDatabase("yellow"));
aInfo.setOpacity(0);
aInfo.setPointsize(36);
aInfo.setFont("Arial");
aInfo.setTextAntialias(true);
aInfo.setText("JMagick Tutorial");
aInfo.setGeometry("+40+40");
mimage.annotateImage(aInfo);
mimage.setFileName("text.jpg");
mimage.writeImage(info);
} catch (MagickException ex) {
Logger.getLogger(LWJGL_IDOMOO_SIMPLE_TEST.class.getName()).log(Level.SEVERE, null, ex);
}
It doesn't work , the JVM crashes with access violation as it probably expects for the input image from IO.

I understand that it may be too late for the answer.Here I wrote this simple code to create a scenario of what you asked.!
private void createEmptyImage() throws MagickException{
ImageInfo newImageiInfo=new ImageInfo();
newImageiInfo.setFileName("src\\main\\resources\\test.jpg");
newImageiInfo.setSize("512x512");
newImageiInfo.setUnits(ResolutionType.PixelsPerInchResolution);
newImageiInfo.setColorspace(ColorspaceType.RGBColorspace);
newImageiInfo.setBorderColor(PixelPacket.queryColorDatabase("red"));
newImageiInfo.setDepth(8);
MagickImage addTextImage = new MagickImage();
addTextImage.allocateImage(newImageiInfo);
addTextImage.setYResolution(480);
addTextImage.setXResolution(640);
addTextImage.writeImage(newImageiInfo);
DrawInfo aInfo = new DrawInfo(newImageiInfo);
aInfo.setFill(PixelPacket.queryColorDatabase("green"));
aInfo.setUnderColor(PixelPacket.queryColorDatabase("yellow"));
aInfo.setOpacity(0);
aInfo.setPointsize(36);
aInfo.setFont("Arial");
aInfo.setTextAntialias(true);
aInfo.setText("JMagick Tutorial");
aInfo.setGeometry("+50+50");
addTextImage.annotateImage(aInfo);
addTextImage.setFileName("src\\main\\resources\\test-result.jpg");
addTextImage.writeImage(newImageiInfo);
}

Here is a Clojure example to create a blue image using JMagick:
(import '[magick MagickImage ImageInfo ColorspaceType])
(def image (MagickImage.))
(.constituteImage image 256 256 "RGB" (byte-array (take (* 3 256 256) (cycle [0 0 255]))))
(def info (ImageInfo.))
(.setSize info "256x256")
(.setDepth info 8)
(.setColorspace info ColorspaceType/RGBColorspace)
(.setFileName image "test.jpg")
(.writeImage image info)

Related

Decode h264 video to java.awt.image.BufferedImage in java

I am trying to make an AirPlay server in java with this library. I am able to start the server and connect to it and I am getting video input, however the input is in h264 format and I tried decoding it with JCodec but it always says I need an sps/pps and I don't know how to create/find this with just a byte[]. This is the onVideo method which is pretty much just copy-pasted from some websites:
#Override
public void onVideo(byte[] video) {
try {
videoFileChannel.write(ByteBuffer.wrap(video));
ByteBuffer bb = ByteBuffer.wrap(video);
H264Decoder decoder = new H264Decoder();
decoder.addSps(List.of(ByteBuffer.wrap(video)));
Picture out = Picture.create(1920, 1088, ColorSpace.YUV420);
var real = decoder.decodeFrame(bb, out.getData());
// decoder.decodeFrame prints "[WARN] . (:0): Skipping frame as no SPS/PPS have been seen so far..." in console and returns null => NullPointer in next line
var img = AWTUtil.toBufferedImage(real.createCompatible());
// ...
} catch (IOException e) {
e.printStackTrace();
}
}
Edit: I've uploaded a ("working") version to github, but the decoded image is discolored and doesn't update all pixels so when something is on the screen and the frame changes, that something can still be on the image.

How to crop the image within a print screen?

I am developing an application that chooses an image of a wound and displays it on the application screen. with this, the user marks the region of interest of the wound, so that later the algorithm can recognize and process the region of interest. I'm doing this using the lib implementation 'com.github.gcacace: signature-pad: 1.2.1' to demarcate the region and then I'm saving the screen's "printscreen" so I can save the markup along with the image of the wound.
How I wish the image will look
Exit:
However, I want to cut the printscreen according to the image of the wound to send to the server to process the image. Can someone help me cut out the wound image after marking.
private fun saveImage(myBitmap: Bitmap?): String? {
try {
// image naming and path to include sd card appending name you choose for file
val mPath = Environment.getExternalStorageDirectory().toString() + "/imagesignature.jpg"
// create bitmap screen capture
val v1 = window.decorView.rootView
v1.isDrawingCacheEnabled = true
val bitmap = Bitmap.createBitmap(v1.drawingCache)
v1.isDrawingCacheEnabled = false
val imageFile = File(mPath)
val outputStream = FileOutputStream(imageFile)
val quality = 100
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream)
outputStream.flush()
outputStream.close()
//setting screenshot in imageview
val filePath = imageFile.path
val ssbitmap = BitmapFactory.decodeFile(imageFile.absolutePath)
imagem.setImageBitmap(ssbitmap)
} catch (e: Throwable) {
// Several error may come out with file handling or DOM
e.printStackTrace()
}
return ""
}
I am still a learner so for an easy way to crop an image I would suggest using this library:
https://github.com/ArthurHub/Android-Image-Cropper
This is where you can crop the image as per your requirement and store the image on the server
If you have the coordinates of the rectangle you want to save:
Bitmap croppedBmp = Bitmap.createBitmap(originalBmp, rectanglePositionX, rectanglePositionY, rectangleWidth, rectangleHeight);
Or you can try:
BitmapFactory.decodeStream(InputStream is, Rect outPadding, Options opts)
or
BitmapFactory.decodeFileDescriptor(FileDescriptor fd, Rect outPadding, Options opts)
where in the Rect outPadding you will set the coordinates of the rectangle you want to save.
As far as I know, I don't think it's possible to crop and image. In order to crop, you need to find the dimensions for the part that you want. I don't think you can tell the program the dimensions of what you want and then crop everything else off, as far as my knowledge goes. It might be possible to print an image, but I don't think Java can crop. Other coding programs might work better for this.

How to get im4java working with BufferedImage

I am using im4java version 1.4.0 to access ImageMagick functionality from Java. It is working well for processing images to and from files.
The Developers Guide has a section on using Buffered Images instead of writing output to a file, and there is a test (TestCase13) that demonstrate using Buffered Images as output. However, when I run any action with a Buffered Image I receive an org.im4java.core.CommandException stating: no ImageReader for given format.
I have tried a number of different things (including adding the jai_imageio.jar to provide additional formats), but nothing seems to work. A basic test-code that shows the problem, (based on im4java.jar's TestCase13) is:
#Test
public void shouldWorkWithBufferedImageTest() throws InterruptedException, IOException, IM4JavaException {
ProcessStarter.setGlobalSearchPath("C:\\Program Files\\ImageMagick-6.8.9-Q8");
String iImageDir = "C:\\images";
String var1 = "png";
IMOperation imOp = new IMOperation();
imOp.addImage(new String[]{iImageDir + "sample-image=6.png"});
imOp.blur(Double.valueOf(2.0D)).paint(Double.valueOf(10.0D));
imOp.addImage(new String[]{var1 + ":-"});
ConvertCmd convertCmd = new ConvertCmd();
Stream2BufferedImage stream2BufferedImage = new Stream2BufferedImage();
convertCmd.setOutputConsumer(stream2BufferedImage);
convertCmd.run(imOp, new Object[0]);
BufferedImage outImage = stream2BufferedImage.getImage();
ImageIO.write(outImage, "PNG", new File(iImageDir + "tmpfile.png"));
DisplayCmd.show(iImageDir + "tmpfile.png");
}
Running this throws the following error:
org.im4java.core.CommandException: java.lang.IllegalStateException: no ImageReader for given format
at org.im4java.core.ImageCommand.run(ImageCommand.java:219)
at test.groovy.services.ImageManipulation.JavaBufferedImageManipulationTest.shouldWorkBufferedImageTest(JavaBufferedImageManipulationTest.java:31)
Caused by: java.lang.IllegalStateException: no ImageReader for given format
at org.im4java.core.Stream2BufferedImage.consumeOutput(Stream2BufferedImage.java:82)
at org.im4java.process.ProcessStarter.processOutput(ProcessStarter.java:276)
at org.im4java.process.ProcessStarter.access$200(ProcessStarter.java:54)
at org.im4java.process.ProcessStarter$2.call(ProcessStarter.java:433)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.lang.Thread.run(Thread.java:745)
The error occurs on the the convertCmd.run line, however, the problem seems to be with setting the outputConsumer as the stream2BufferedImage. How do I fix this? Is there a known bug with im4java and BufferedImages? Is there a better work-around than exporting to a temp-file and then reading it back in to a BufferedImage? I am aware of JMagick (as an alternative to im4java) but have not found this a good solution for other reasons.
Thanks, in advance, for any assistance or ideas.
see in this example i have the input source as buffered Image and output is also as buffered image . I hope this can help you.
public static void main(String... args) throws Exception {
IMOperation op = new IMOperation();
op.addImage();
op.resize(350)
op.addImage("png:-")
BufferedImage images = ImageIO.read(new File("image.jpg"));
// set up command
ConvertCmd convert = new ConvertCmd();
Stream2BufferedImage s2b = new Stream2BufferedImage();
convert.setOutputConsumer(s2b);
// run command and extract BufferedImage from OutputConsumer
convert.run(op,images);
BufferedImage img = s2b.getImage();
}

"mimetype: application" display on a picture instead of "mimetype: image" after a ImageIO.write

When I simply create a new image from another like this:
public static void scaleByTwoRight(String src, String dest)
throws IOException {
BufferedImage bsrc = ImageIO.read(new File(src));
int width = bsrc.getWidth()/2;
int height = bsrc.getHeight();
BufferedImage bdest = bsrc.getSubimage(width, 0, width, height);
ImageIO.write(bdest,"PNG",new File(dest));
}
Source file (src) = C:...\Manga\Shonan Juna_ Gumi Tome 11\Shonan Junaï Gumi Tome 11 - 091B.png
Destination file (dest) = C:...\Manga\Shonan Junaï Gumi Tome 11 - 091B_A.png
Example of generated file: https://docs.google.com/file/d/0B1vKCZzB5hxqYzNsUWF5RHA2Wm8/edit?usp=sharing
Problem: The new image has mimetype: application instead of mimetype: image
How I arrive to this conclusion: I'm using a function to test if the file is an image or not:
public static boolean isImage(String src)
throws IOException {
File f = new File(src);
String mimetype= new MimetypesFileTypeMap().getContentType(f);
String type = mimetype.split("/")[0];
if(type.equals("image")){
return true;
}else{
System.out.println("mimetype: "+type);
return false;
}
}
It has not a huge impact if the Mime-type is not correct but I prefer to have that working properly..
Thanks for your help!
Note:
I'm running under Windows 7 / 32b
JVM 1.7 / Eclipse Helios
Your code is working fine in my machine.
I have windows XP,32 bit,
Tried with jpeg image and it is returning the mimetype as image/jpeg only.
Hope you are not trying to execute both the functions simultaneously.
Also the destination file name should contain proper extension like .jpeg or. png etc...

Taking screenshot with Java applet using Java Robot class not working

I am using a Java applet to take a screenshot of the web browser, using Java's Robot class.
Robot objRobot = new Robot ();
BufferedImage objBufferedImage = objRobot.createScreenCapture(objRectArea);
The thing works good in Windows system, taking screenshot. But in case of Mac OS X I get a blank image.
When I check the event viewer, I see the following error:
invalid context
invalid pixel format
CoreAnimation: rendering error 506
The problem is occurring for all the browsers Safari, Firefox and Chrome. My applet is a signed applet.
What might be the reason?
My machine configuration is as follows:
OS : MAC OS X
Version : 10.6.4
I've sent the error message invalid pixel format to google and received a long list of results (close to 10.000) - it looks as if the problem is not a Java problem but a configuration issue on your Mac.
Try to change display resolutions and re-run your applet. Good chance, that the error is linked to some screen resolutions (external display?). Some suggestions on the web were to fully update you OSX.
dir Robot objRobot = null;
try
{
objRobot = new Robot();
} catch(Exception ex)
{
}
Dimension screenDim = Toolkit.getDefaultToolkit().getScreenSize();
BufferedImage objBufferedImage = objRobot.createScreenCapture(new Rectangle(0, 0, (int)screenDim.getWidth(), (int)screenDim.getHeight()));
int areaToExportWidth = 1024;
int areaToExportHeight = 768;
//Create the image
BufferedImage exportImage =objRobot.createScreenCapture(new Rectangle(0, 0, (int)screenDim.getWidth(), (int)screenDim.getHeight()));
//Get graphics - Get the layer we can actually draw on
Graphics2D imageGraphics = (Graphics2D) exportImage.getGraphics();
//Cleanup after ourselves
imageGraphics.dispose();
//Setup to write the BufferedImage to a file
String pathToFile = "dir";
File outputDirectory = new File(pathToFile);
File outputFile = new File(pathToFile+"\\"+counter+"MyImage.png");
//Here we make sure the directory exists.
/*
* Returns TRUE if:
* The directory is MISSING
* and/or the directory IS NOT a directory
*/
if(!outputDirectory.exists() || !outputDirectory.isDirectory()){
outputDirectory.mkdirs(); //Make the directory
} // Else do nothing
//Write the file
try { //Attempt the write
ImageIO.write(exportImage, "png", outputFile);
} catch (IOException e) { //For some reason it failed so...
e.printStackTrace(); //... why did it fail?
}

Categories

Resources