Video buffer delay with MJPG Feed - java

I am trying to delay my live mjpeg video feed by 10 seconds.
I am trying to modify this code and but I am unable to incorporate the mjpg url.
It keeps on saying 'The constructor CaptureMJPEG(String, int, int, int) is undefined' when I try to put the url in.
The original line said:
capture = new CaptureMJPEG(this, capture_xsize, capture_ysize, capture_frames);
I changed it to:
capture = new CaptureMJPEG ("http:/url.com/feed.mjpg", capture_xsize, capture_ysize, capture_frames);
import processing.video.*;
import it.lilik.capturemjpeg.*;
Capture myCapture;
CaptureMJPEG capture;
VideoBuffer monBuff;
int display_xsize = 800; // display size
int display_ysize = 600;
int capture_xsize = 320; // capture size
int capture_ysize = 240;
int delay_time = 10; // delay in seconds
int capture_frames = 20; // capture frames per second
void setup() {
size(display_xsize,display_ysize, P3D);
// Warning: VideoBuffer must be initiated BEFORE capture- or movie-events start
monBuff = new VideoBuffer(delay_time*capture_frames, capture_xsize,capture_ysize);
capture = new CaptureMJPEG ("http:/url.com/feed.mjpg", capture_xsize, capture_ysize, capture_frames);
}
void captureEvent(Capture capture) {
capture.read();
monBuff.addFrame( capture );
}
void draw() {
PImage bufimg = monBuff.getFrame();
PImage tmpimg = createImage(bufimg.width,bufimg.height,RGB);
tmpimg.copy(bufimg,0,0,bufimg.width,bufimg.height,0,0,bufimg.width,bufimg.height);
tmpimg.resize(display_xsize,display_ysize);
image( tmpimg, 0, 0 );
}
class VideoBuffer
{
PImage[] buffer;
int inputFrame = 0;
int outputFrame = 0;
int frameWidth = 0;
int frameHeight = 0;
/*
parameters:
frames - the number of frames in the buffer (fps * duration)
width - the width of the video
height - the height of the video
*/
VideoBuffer( int frames, int width, int height )
{
buffer = new PImage[frames];
for(int i = 0; i < frames; i++)
{
this.buffer[i] = new PImage(width, height);
}
this.inputFrame = frames - 1;
this.outputFrame = 0;
this.frameWidth = width;
this.frameHeight = height;
}
// return the current "playback" frame.
PImage getFrame()
{
int frr;
if(this.outputFrame>=this.buffer.length)
frr = 0;
else
frr = this.outputFrame;
return this.buffer[frr];
}
// Add a new frame to the buffer.
void addFrame( PImage frame )
{
// copy the new frame into the buffer.
System.arraycopy(frame.pixels, 0, this.buffer[this.inputFrame].pixels, 0, this.frameWidth * this.frameHeight);
// advance the input and output indexes
this.inputFrame++;
this.outputFrame++;
// wrap the values..
if(this.inputFrame >= this.buffer.length)
{
this.inputFrame = 0;
}
if(this.outputFrame >= this.buffer.length)
{
this.outputFrame = 0;
}
}
}

Reading the reference docs:
https://bytebucket.org/nolith/capturemjpeg/wiki/api/index.html
These are the only two constructors:
CaptureMJPEG(PApplet parent, String url)
Creates a CaptureMJPEG without HTTP Auth credential
CaptureMJPEG(PApplet parent, String url, String username, String password)
Creates a CaptureMJPEG with HTTP Auth credential
So the first argument must always point to your processing applet instance. So
capture = new CaptureMJPEG (this, "http:/url.com/feed.mjpg", capture_xsize, capture_ysize, capture_frames);

Related

Write text to image in multiple fonts with wrapping in java

I am trying to create an image with a given text and style. eg;
" textStyle(Offer ends 25/12/2016. Exclusions Apply., disclaimer) textStyle(See Details,underline) "
In above line i am splitting and creating a map that stores the first parameter of textStyle block as key and second parameter as value where second param defines the style to be applied on first param. Hence an entry of map will look like .
Now when i iterate over this map to write the text to image i check if the text is overflowing the width. If yes then it breaks the text and adds it to next line in the horizontal center. So for example lets say i am trying to write "Offer ends 25/12/2016. Exclusions Apply." with Arial and font size 12. While writing i find that i can write till "Offer ends 23/12/2016. " only and "Exclusions apply" has to go in next line. But it writes the text in horizontal center neglecting that as there is space left horizontally i can write "See Details" too in the same line.
Please help. Below is the code what i have tried. I have also tried creating a JTextPane and then converting it to image but this cannot be an option as it first creates the frame, makes it visible, writes it and then disposes it. And most of the times i was getting Nullpointer exception on SwingUtilities.invokeAndWait.
Actual : http://imgur.com/7aIlcEQ
Expected http://imgur.com/038zQTZ
public static BufferedImage getTextImage(String textWithoutStyle, Map<String, String> textToThemeMap, Properties prop, int height, int width) {
BufferedImage img = new BufferedImage(width,height,BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g2d = img.createGraphics();
g2d.setPaint(Color.WHITE);
FontMetrics fm = g2d.getFontMetrics();
Map<String, Font> textToFontMap = new LinkedHashMap<String, Font>();
for(Map.Entry<String, String> entry : textToThemeMap.entrySet()) {
if(StringUtils.isNotBlank(entry.getKey()) && StringUtils.isNotBlank(entry.getValue())) {
Font font = getFont(prop, entry.getValue().trim());
g2d.setFont(font);
fm = g2d.getFontMetrics();
String string = entry.getKey();
char[] chars = null;
int i = 0, pixelWidth = 0;
List<String> newTextList = new ArrayList<String>();
if(fm.stringWidth(string) > (width - 10)) {
chars = string.toCharArray();
for (i = 0; i < chars.length; i++) {
pixelWidth = pixelWidth + fm.charWidth(chars[i]);
if(pixelWidth >= (width - 10)) {
break;
}
}
String newString = WordUtils.wrap(string, i, "\n",false);
String[] splitString = newString.split("\n");
for(String str : splitString) {
newTextList.add(str);
textToFontMap.put(string, font);
}
} else {
newTextList.add(string);
textToFontMap.put(string, font);
}
}
}
Font font = new Font("Arial", Font.BOLD, 14);
int spaceOfLineHeight = (textToFontMap.size() - 1) * 7;
int spaceOfText = textToFontMap.size() * font.getSize();
int totalSpace = spaceOfLineHeight + spaceOfText ;
int marginRemaining = height - totalSpace;
int tempHt = marginRemaining / 2 + 10;
String txt = null;
for(Map.Entry<String, Font> entry : textToFontMap.entrySet()) {
txt = entry.getKey();
font = entry.getValue();
g2d.setFont(font);
fm = g2d.getFontMetrics();
int x = (width - fm.stringWidth(txt)) / 2;
int y = tempHt;
g2d.drawString(txt, x, y);
tempHt = tempHt + fm.getHeight();
}
// g2d.drawString(text.getIterator(), 0, (int)lm.getAscent() + lm.getHeight());
// g2d.dispose();
return img;
}
// Code with JTextPane ------------------------------------------
public static BufferedImage getTextImage(final Map < String, String > textToThemeMap, final Properties prop, final int height, final int width) throws Exception {
JFrame f = new JFrame();
f.setSize(width, height);
final StyleContext sc = new StyleContext();
DefaultStyledDocument doc = new DefaultStyledDocument(sc);
final JTextPane pane = new JTextPane(doc);
pane.setSize(width, height);
// Build the styles
final Paragraph[] content = new Paragraph[1];
Run[] runArray = new Run[textToThemeMap.size()];
int i = 0;
for (Map.Entry < String, String > entry: textToThemeMap.entrySet()) {
if (StringUtils.isNotBlank(entry.getValue().trim()) && StringUtils.isNotBlank(entry.getKey().trim())) {
Run run = new Run(entry.getValue().trim(), entry.getKey());
runArray[i++] = run;
}
}
content[0] = new Paragraph(null, runArray);
/*createDocumentStyles(sc, prop,textToThemeMap.values());
addText(pane, sc, sc.getStyle("default"), content);
pane.setEditable(false);*/
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
try {
createDocumentStyles(sc, prop, textToThemeMap.values());
} catch (MalformedURLException e) {
//e.printStackTrace();
}
addText(pane, sc, sc.getStyle("default"), content);
pane.setEditable(false);
}
});
} catch (Exception e) {
System.out.println("Exception when constructing document: " + e);
}
f.getContentPane().add(pane);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D gd = img.createGraphics();
f.paint(gd);
f.dispose();
/*ImageIO.write(img, "png", new File("C:\\Users\\spande0\\Desktop\\a.png"));
System.out.println("done");*/
return img;
}
I suspect the issue is in your 'Y' computation.
int spaceOfLineHeight = (newTextList.size() - 1) * 7;
int spaceOfText = newTextList.size() * font.getSize();
int totalSpace = spaceOfLineHeight + spaceOfText;
int marginRemaining = height - totalSpace;
int tempHt = marginRemaining / 2 + 10;
You have to keep the height occupied by the previous lines, and add it to the current 'Y'.
At the moment, for all the lines, the 'Y' values is same.
Declare prevHeight outside the for loop. and then do the following.
int tempHt = marginRemaining / 2 + 10;
tempHT += prevHeight;
prevHeight = tempHeight
Based on the comments, I will suggest you to break down your function into two smaller functions.
// Loop through the strings and find out how lines are split and calculate the X, Y
// This function will give the expected lines
splitLinesAndComputeResult
// Just render the lines
renderLines

Android - demod FSK using goertzel

I am using this code https://stackoverflow.com/questions/23432398/audio-recorder-in-android-process-the-audio-bytes to capture the mic audio but I am writing the data to a ByteArrayOutputStream. After I finish the record I want to demodule the signal captured by using Goertzel Algorithm. The FSK signal consists out of 2 frequencies, 800Hz for '1' and 400Hz for '0' each bit is moduled using 100 samples. I am using this class of Goertzel: http://courses.cs.washington.edu/courses/cse477/projectwebs04sp/cse477m/code/public/Goertzel.java I am trying to use a bin size of 150.
Here is what I try to do:
the code, after I finish the recording:
private void stopRecording()
{
if(recorder != null)
{
isRecording= false;
recorder.stop();
recorder.release();
recorder = null;
recordingThread = null;
int BlockSize = 150;
float HighToneFrequency = 800;
float LowToneFrequency = 400;
byte[] byteArrayData = ByteArrayAudioData.toByteArray();
/*final AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
8000, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT, byteArrayData.length,
AudioTrack.MODE_STATIC);
audioTrack.write(byteArrayData, 0, byteArrayData.length);
audioTrack.play();*/
double[] daOriginalSine = convertSample2Sine(byteArrayData);
int i = 0;
while(i < daOriginalSine.length)
{
double t1 = testSpecificFrequency(i, HighToneFrequency,BlockSize, daOriginalSine);
double t2 = testSpecificFrequency(i, LowToneFrequency,BlockSize, daOriginalSine);
i+=BlockSize;
}
}
}
And the function testSpecificFrequency:
private double testSpecificFrequency(int startIndex, float ToneFreq, int BlockSize, double[] sample)
{
Goertzel g = new Goertzel(RECORDER_SAMPLERATE, ToneFreq, BlockSize, false);
g.initGoertzel();
for(int j=startIndex ; j<startIndex+BlockSize ; j++)
{
g.processSample(sample[j]);
}
double res= Math.sqrt(g.getMagnitudeSquared());
return res;
}
I just tried to see what will be the results, by sending 800Hz to the constructor and afterwars sending 400Hz,don't really know how to proceed from this point =\
Any ideas?

How to read from a persian pdf file in java

I want read a pdf file that contains Persian characters using itext . I read from this , but words are reverse. For example "ره" instead of "هر" .
I split it with "\n" and read every text in every line from end , but i think that maybe there is a better solution to read from this Pdf .
That is my code :
public class Main extends JFrame {
private static final int WIDTH = 600;
private static final int HEIGHT = 600;
/**
* by Shomeis
*/
private static final long serialVersionUID = 1L;
public Main() {
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
int x = dim.width / 2 - WIDTH / 2;
int y = dim.height / 2 - HEIGHT / 2;
setBounds(x, y, WIDTH, HEIGHT);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setMinimumSize(new Dimension(600, 600));
//
File pdf = new File("E:\\guide1.pdf");
if (!pdf.canRead() || !pdf.isFile()) {
System.err.println("cannot read input file " + pdf.getAbsolutePath());
return;
}
try {
PdfReader reader = new PdfReader(pdf.getAbsolutePath());
String page;
String areaText = "";
System.out.println(reader.getNumberOfPages());
for (int k = 1; k <= reader.getNumberOfPages(); k++) {
System.out.println(k);
page = PdfTextExtractor.getTextFromPage(reader, k);
String[] b = page.split("\n");
for (int i = 0; i < b.length; i++) {
for (int j = (b[i].length() - 1); j >= 0; j--) {
areaText += b[i].charAt(j);
}
areaText += "\n";
}
}
JTextArea text = new JTextArea(areaText);
JScrollPane sc = new JScrollPane(text);
text.setWrapStyleWord(true);
text.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
this.setContentPane(sc);
this.setVisible(true);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
new Main().setVisible(true);
}
}
You can reverse the words:
String res = strategy.getResultantText();
res = new StringBuilder(res).reverse().toString();

ImageJ API: Getting RGB values from image

I am trying to obtain RGB values from an ImagePlus object. I am getting an exception error when I attempt to do this:
import ij.IJ;
import ij.ImagePlus;
import ij.plugin.filter.PlugInFilter;
import ij.process.ColorProcessor;
import ij.process.ImageProcessor;
import java.awt.image.IndexColorModel;
public class ImageHelper implements PlugInFilter {
public int setup(String arg, ImagePlus img) {
return DOES_8G + NO_CHANGES;
}
public void run(ImageProcessor ip) {
final int r = 0;
final int g = 1;
final int b = 2;
int w = ip.getWidth();
int h = ip.getHeight();
ImagePlus ips = new ImagePlus("C:\\Lena.jpg");
int width = ips.getWidth();
int height = ips.getHeight();
System.out.println("width of image: " + width + " pixels");
System.out.println("height of image: " + height + " pixels");
// retrieve the lookup tables (maps) for R,G,B
IndexColorModel icm = (IndexColorModel) ip.getColorModel();
int mapSize = icm.getMapSize();
byte[] Rmap = new byte[mapSize];
icm.getReds(Rmap);
byte[] Gmap = new byte[mapSize];
icm.getGreens(Gmap);
byte[] Bmap = new byte[mapSize];
icm.getBlues(Bmap);
// create new 24-bit RGB image
ColorProcessor cp = new ColorProcessor(w, h);
int[] RGB = new int[3];
for (int v = 0; v < h; v++) {
for (int u = 0; u < w; u++) {
int idx = ip.getPixel(u, v);
RGB[r] = Rmap[idx];
RGB[g] = Gmap[idx];
RGB[b] = Bmap[idx];
cp.putPixel(u, v, RGB);
}
}
ImagePlus cwin = new ImagePlus("RGB Image", cp);
cwin.show();
}
}
The exception is comming from this line:
IndexColorModel icm = (IndexColorModel) ip.getColorModel();
Exception:
Exception in thread "main" java.lang.ClassCastException:
java.awt.image.DirectColorModel cannot be cast to
java.awt.image.IndexColorModel
...Any ideas? ^_^
The error occurs beccause ip.getColorModel() does not return a IndexColorModel object, but a ColorModel object.
To get the IndexColorModel object, you should use the following code:
IndexColorModel icm = ip.getDefaultColorModel();
That should give you a IndexColorModel, according to the ImageJ API.
ColorProcessor contains methods
getChannel()
to get the red, green or blue channels.
To get a ColorProcessor you can cast your processor to ColorProcessor.
ColorProcessor cp = (ColorProcessor) ip;
It would throw an error if the image was a grayscale though.

Loading an animated image to a BufferedImage array

I'm trying to implement animated textures into an OpenGL game seamlessly. I made a generic ImageDecoder class to translate any BufferedImage into a ByteBuffer. It works perfectly for now, though it doesn't load animated images.
I'm not trying to load an animated image as an ImageIcon. I need the BufferedImage to get an OpenGL-compliant ByteBuffer.
How can I load every frames as a BufferedImage array in an animated image ?
On a similar note, how can I get the animation rate / period ?
Does Java handle APNG ?
The following code is an adaption from my own implementation to accommodate the "into array" part.
The problem with gifs is: There are different disposal methods which have to be considered, if you want this to work with all of them. The code below tries to compensate for that. For example there is a special implementation for "doNotDispose" mode, which takes all frames from start to N and paints them on top of each other into a BufferedImage.
The advantage of this method over the one posted by chubbsondubs is that it does not have to wait for the gif animation delays, but can be done basically instantly.
BufferedImage[] array = null;
ImageInputStream imageInputStream = ImageIO.createImageInputStream(new ByteArrayInputStream(data)); // or any other source stream
Iterator<ImageReader> imageReaders = ImageIO.getImageReaders(imageInputStream);
while (imageReaders.hasNext())
{
ImageReader reader = (ImageReader) imageReaders.next();
try
{
reader.setInput(imageInputStream);
frames = reader.getNumImages(true);
array = new BufferedImage[frames];
for (int frameId : frames)
{
int w = reader.getWidth(0);
int h = reader.getHeight(0);
int fw = reader.getWidth(frameId);
int fh = reader.getHeight(frameId);
if (h != fh || w != fw)
{
GifMeta gm = getGifMeta(reader.getImageMetadata(frameId));
// disposalMethodNames: "none", "doNotDispose","restoreToBackgroundColor","restoreToPrevious",
if ("doNotDispose".equals(gm.disposalMethod))
{
image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D) image.getGraphics();
for (int f = 0; f <= frameId; f++)
{
gm = getGifMeta(reader.getImageMetadata(f));
if ("doNotDispose".equals(gm.disposalMethod))
{
g.drawImage(reader.read(f), null, gm.imageLeftPosition, gm.imageTopPosition);
}
else
{
// XXX "Unimplemented disposalMethod (" + getName() + "): " + gm.disposalMethod);
}
}
g.dispose();
}
else
{
image = reader.read(frameId);
// XXX "Unimplemented disposalMethod (" + getName() + "): " + gm.disposalMethod;
}
}
else
{
image = reader.read(frameId);
}
if (image == null)
{
throw new NullPointerException();
}
array[frame] = image;
}
}
finally
{
reader.dispose();
}
}
return array;
private final static class GifMeta
{
String disposalMethod = "none";
int imageLeftPosition = 0;
int imageTopPosition = 0;
int delayTime = 0;
}
private GifMeta getGifMeta(IIOMetadata meta)
{
GifMeta gm = new GifMeta();
final IIOMetadataNode gifMeta = (IIOMetadataNode) meta.getAsTree("javax_imageio_gif_image_1.0");
NodeList childNodes = gifMeta.getChildNodes();
for (int i = 0; i < childNodes.getLength(); ++i)
{
IIOMetadataNode subnode = (IIOMetadataNode) childNodes.item(i);
if (subnode.getNodeName().equals("GraphicControlExtension"))
{
gm.disposalMethod = subnode.getAttribute("disposalMethod");
gm.delayTime = Integer.parseInt(subnode.getAttribute("delayTime"));
}
else if (subnode.getNodeName().equals("ImageDescriptor"))
{
gm.imageLeftPosition = Integer.parseInt(subnode.getAttribute("imageLeftPosition"));
gm.imageTopPosition = Integer.parseInt(subnode.getAttribute("imageTopPosition"));
}
}
return gm;
}
I don't think Java supports APNG by default, but you can use an 3rd party library to parse it:
http://code.google.com/p/javapng/source/browse/trunk/javapng2/src/apng/com/sixlegs/png/AnimatedPngImage.java?r=300
That might be your easiest method. As for getting the frames from an animated gif you have to register an ImageObserver:
new ImageIcon( url ).setImageObserver( new ImageObserver() {
public void imageUpdate( Image img, int infoFlags, int x, int y, int width, int height ) {
if( infoFlags & ImageObserver.FRAMEBITS == ImageObserver.FRAMEBITS ) {
// another frame was loaded do something with it.
}
}
});
This loads asynchronously on another thread so imageUpdate() won't be called immediately. But it will be called for each frame as it parses it.
http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/image/ImageObserver.html

Categories