Captured frame is rotating 90 degree right in the Server - java

Frame or image is captured from the Video sent by the android mobile, Used
Jcodec(<artifactId>jcodec</artifactId> and <artifactId>jcodec-javase</artifactId> Version 0.2.2) to capture the image in java. Everything is working fine but while displaying the photo is tilted to right 90 degree. I am not able to find that rotating is happening while capturing the frame or while displaying it!
In local server(tomcat7) working fine(image is in potrait itself) but this issue occured when I push the code to AWS it has tomcat8. AND after downloaded, size of the image(JPEG) from AWS is 28kb, from local server is 118kb.
I am sharing my code here Anyone Please tell me where it is going wrong and any links to solve this issue will be greatful.
Frame Capturing Code:
int frameNumber = 1;
Picture picture = FrameGrab.getFrameFromFile(file, frameNumber);
BufferedImage bufferedImage = AWTUtil.toBufferedImage(picture);
ImageIO.write(bufferedImage, "jpg", new File(id + File.separator + fileName + "_" + fileName + ".jpg"));
Image displying code:
public ResponseEntity<Resource> getPhoto(#PathVariable(value = "id") Integer id) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.IMAGE_JPEG);
String absolutePath = new File(".").getAbsolutePath();
File file = new File(Paths.get(absolutePath).getParent() + "/" + id);
if (null != file) {
FilenameFilter beginswithm = new FilenameFilter() {
public boolean accept(File directory, String filename) {
return filename.startsWith("photo");
}
};
File[] files = file.listFiles(beginswithm);
if (null != files && files.length > 0) {
Resource resource = null;
for (final File f : files) {
headers.set("Content-Disposition", "inline; filename=" + f.getName());
resource = appContext.getResource("file:"
+ Paths.get(absolutePath).getParent() + "/" + id + "/" + f.getName());
return new ResponseEntity<>(resource, headers, HttpStatus.OK);
}
}
}
RecruiterResponseBean resBean = new RecruiterResponseBean();
resBean.setStatusMessage(Constants.FAILED);
resBean.setStatusCode(Constants.FAILED_CODE);
return new ResponseEntity(resBean, HttpStatus.NOT_FOUND);
}

In android, You can use ExifInterface to find out if the image/video has a rotation.
ExifInterface exifInterface = new ExifInterface(mFile.getPath());
int orientation = exifInterface.getAttributeInt(TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
Matrix matrix = new Matrix();
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
matrix.postRotate(90);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
matrix.postRotate(180);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
matrix.postRotate(270);
break;
default:
break;
}

Related

How do I extract all the frames from a video in Java?

I'm trying to grab the frames from a video and put them into a collection of BufferedImage so I can use the images later. I tried to use the code in the second answer for this question, but it wasn't really helpful because the code they provided only grabs the first frame. How would I extract all the frames and put them into a collection?
So, a little bit of Googling (and reading the source code), was I able to hobble together this basic concept.
The "obvious" solution was to loop over the frames in the video and extract them, the "un-obvious" solution was "how"?!
The two methods you need are FFmpegFrameGrabber#getLengthInFrames and FFmpegFrameGrabber#setFrameNumber, from there it's just a simple method of converting the current frame and writing it to a file (which has already been demonstrated from the previous question)
File videoFile = new File("Storm - 106630.mp4");
FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(videoFile.getAbsoluteFile());
frameGrabber.start();
Java2DFrameConverter c = new Java2DFrameConverter();
int frameCount = frameGrabber.getLengthInFrames();
for (int frameNumber = 0; frameNumber < frameCount; frameNumber++) {
System.out.println("Extracting " + String.format("%04d", frameNumber) + " of " + String.format("%04d", frameCount) + " frames");
frameGrabber.setFrameNumber(frameNumber);
Frame f = frameGrabber.grab();
BufferedImage bi = c.convert(f);
ImageIO.write(bi, "png", new File("Frame " + String.format("%04d", frameNumber) + "-" + String.format("%04d", frameCount) + ".png"));
}
frameGrabber.stop();
Now, obviously, you could store the images into some kind of List in memory, just beware, depending on the size and length of the original video, this might run you into memory issues.
You can use OpenCV to extract frames in a video, try the below code. input is the video file path of your computer
VideoCapture cap = new VideoCapture();
String output = "resources/output";
cap.open(input);
int video_length = (int) cap.get(Videoio.CAP_PROP_FRAME_COUNT);
int frames_per_second = (int) cap.get(Videoio.CAP_PROP_FPS);
Mat frame = new Mat();
if (cap.isOpened()) {
System.out.println("Video is opened");
System.out.println("Number of Frames: " + video_length);
System.out.println(frames_per_second + " Frames per Second");
System.out.println("Converting Video to images...");
cap.read(frame);
int frame_number = 0;
while (cap.read(frame)) {
Imgcodecs.imwrite(output + "/" + frame_number + ".jpg", frame);
frame_number++;
}
cap.release();
processingStatus = video_length + " Frames extracted";
System.out.println(processingStatus);
} else {
processingStatus = "Failed";
System.out.println(processingStatus);
}

how to take color screenshot using selenium java

screenshots is getting captured like below images but i want to capture it in actual colors also i don't know the reason behind it can anybody tell me why this is happening?
((JavascriptExecutor)driver).executeScript("window.scrollBy(0,131)");
int yPosition = Decision_Maker.getLocation().getY();
for(int j = 1; j<=list.size(); j++)
{
// Get entire page screenshot
File screenshots = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
BufferedImage fullImg = ImageIO.read(screenshots);
ImageIO.read(screenshots).getHeight();
// Get width and height of the element
int eleWidth = Decision_Maker.getSize().getWidth();
int eleHeight = Decision_Maker.getSize().getHeight();
//Crop the entire page screenshot to get only element screenshot
BufferedImage eleScreenshot= fullImg.getSubimage(465, 190,eleWidth,eleHeight);
ImageIO.write(eleScreenshot, "jpg", screenshots);
//Scroll vertically to the element
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("window.scroll (0, " + yPosition + ") ");
yPosition = yPosition + eleHeight;
//wait for sometime
Thread.sleep(3000);
//File Location
String location = "E:\\Automation\\Screenshots\\";
Thread.sleep(3000);
//capture screenshot
FileUtils.copyFile(screenshots, new File (location + "img" + i + ".jpg"));
Thread.sleep(3000L);
}
You can create utils class to take screenshot and use it
public static void TakeScreenshot(String filename) throws IOException
{
File file= ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(file, new File("path to store screenshot" + filename + ".jpg"));
}

Warning: You did not close a PDF Document looping when renderImageWithDPI

i want to split pdf to image file by page, but i got Warning: You did not close a PDF Document looping when renderImageWithDPI
Still have warning
UPDATE CODE :
public void splitImage(PDDocument document, File checkFile, File theDirSplit, String fileExtension, File theDir, File watermarkDirectory, int numberOfPages)
throws InvalidPasswordException, IOException {
String fileName = checkFile.getName().replace(".pdf", "");
int dpi = 300;
if (theDirSplit.list().length < numberOfPages)
{
for (int i = 0; i < numberOfPages; ++i)
{
if (i == numberOfPages)
break;
if (theDirSplit.list().length != numberOfPages)
{
File outPutFile = new File(theDirSplit + Constan.simbol + fileName + "_" + (i + 1) + "." + fileExtension);
document = PDDocument.load(checkFile);
PDFRenderer pdfRenderer = new PDFRenderer(document);
BufferedImage bImage = pdfRenderer.renderImageWithDPI(i, dpi, ImageType.RGB);
ImageIO.write(bImage, fileExtension, outPutFile);
}
// splitService.watermark(outPutFile, (i + 1), watermarkDirectory, "pdf");
}
document.close();
//System.out.println("Converted Images are saved at -> " + theDirSplit.getAbsolutePath());
}
System.out.println("Done Partial SPlit");
/*
* int i = 1; while (iterator.hasNext()) { PDDocument pd = iterator.next();
* pd.save(theDirSplit + Constan.simbol + i++ + ".pdf"); }
* System.out.println("Multiple PDF’s created");
*/
}
error looping
total warning same with number of pages...
i already try to close but not work, this process make my server java.lang.OutOfMemoryError: Java heap space
update :
else if ("pdf".equalsIgnoreCase(typeFile)) {
System.out.println(
"target file " + downloadPath + R_OBJECT_ID + Constan.simbol + R_OBJECT_ID + "." + typeFile);
//get jumlah halaman
try(PDDocument document = PDDocument.load(checkFile)){
File theDirSplit = new File(theDir.getAbsolutePath() + Constan.simbol + "splitImage");
createFolder(theDirSplit);
String fileExtension = "jpeg";
File watermarkDirectory = new File(theDir.getAbsolutePath() + Constan.simbol + "watermarkImage");
createFolder(watermarkDirectory);
// split 2 page image
if (theDirSplit.list().length <= document.getNumberOfPages()) {
try {
splitImage(document,checkFile, theDirSplit, fileExtension, theDir, watermarkDirectory, document.getNumberOfPages()/2);
} catch (IOException e) {
System.out.println("ERROR SPLIT PDF " + e.getMessage());
e.printStackTrace();
}
}
res.setTotalPages(document.getNumberOfPages());
document.close();
return new ResponseEntity<>(res, HttpStatus.OK);
}
} else {
res.setTotalPages(1);
return new ResponseEntity<>(res, HttpStatus.OK);
}
this is code to call split method....
This is somewhat lost from the question, but the cause was failing to close the documents generated by splitter.split().

How to increment the filename number if the file exists

How can I increment the filename if the file already exists?
Here's the code that I am using -
int num = 0;
String save = at.getText().toString() + ".jpg";
File file = new File(myDir, save);
if (file.exists()) {
save = at.getText().toString() + num + ".jpg";
file = new File(myDir, save);
num++;
}
This code works, but only two files are saved, like file.jpg and file2.jpg.
This problem is to always initialize num = 0, so if file exists, it saves file0.jpg and does not check whether file0.jpg exists.
So, to code work. You should check until it is available:
int num = 0;
String save = at.getText().toString() + ".jpg";
File file = new File(myDir, save);
while(file.exists()) {
save = at.getText().toString() + (num++) + ".jpg";
file = new File(myDir, save);
}
Try this:
File file = new File(myDir, at.getText().toString() + ".jpg");
for (int num = 0; file.exists(); num++) {
file = new File(myDir, at.getText().toString() + num + ".jpg");
}
// Now save/use your file here
In addition to the first answer, I made some more changes:
private File getUniqueFileName(String folderName, String searchedFilename) {
int num = 1;
String extension = getExtension(searchedFilename);
String filename = searchedFilename.substring(0, searchedFilename.lastIndexOf("."));
File file = new File(folderName, searchedFilename);
while (file.exists()) {
searchedFilename = filename + "(" + (num++) + ")" + extension;
file = new File(folderName, searchedFilename);
}
return file;
}
int i = 0;
String save = at.getText().toString();
String filename = save +".jpg";
File f = new File(filename);
while (f.exists()) {
i++;
filename =save+ Integer.toString(i)+".jpg";
f = new File(filename);
}
f.createNewFile();
You can avoid the code repetition of some of the answers here by using a do while loop
Here's an example using the newer NIO Path API introduced in Java 7
Path candidate = null;
int counter = 0;
do {
candidate = Paths.get(String.format("%s-%d",
path.toString(), ++counter));
} while (Files.exists(candidate));
Files.createFile(candidate);
Kotlin version:
private fun checkAndRenameIfExists(name: String): File {
var filename = name
val extension = "pdf"
val root = Environment.getExternalStorageDirectory().absolutePath
var file = File(root, "$filename.$extension")
var n = 0
while (file.exists()) {
n += 1
filename = "$name($n)"
file = File(root, appDirectoryName + File.separator + "$filename.$extension")
}
return file
}
Another simple logic solution to get the unique file name under a directory using Apache Commons IO using WildcardFileFilter to match the file name and get the number of exists with the given name and increment the counter.
public static String getUniqueFileName(String directory, String fileName) {
String fName = fileName.substring(0, fileName.lastIndexOf("."));
Collection<File> listFiles = FileUtils.listFiles(new File(directory), new WildcardFileFilter(fName + "*", IOCase.INSENSITIVE), DirectoryFileFilter.DIRECTORY);
if(listFiles.isEmpty()) {
return fName;
}
return fName.concat(" (" + listFiles.size() + ")");
}
This is the solution I use to handle this case. It works for folders as well as for files.
var destination = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "MyFolder")
if (!destination.exists()) {
destination.mkdirs()
} else {
val numberOfFileAlreadyExist =
destination.listFiles().filter { it.name.startsWith("MyFolder") }.size
destination = File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
"MyFolder(${numberOfFileAlreadyExist + 1})"
)
destination.mkdirs()
}
Having needed to solve this problem in my own code, I took Tejas Trivedi's answer, made it work like Windows when you happen to download the same file several times.
// This function will iteratively to find a unique file name to use when given a file: example (###).txt
// More or less how Windows will save a new file when one already exists: 'example.txt' becomes 'example (1).txt'.
// if example.txt already exists
private File getUniqueFileName(File file) {
File originalFile = file;
try {
while (file.exists()) {
String newFileName = file.getName();
String baseName = newFileName.substring(0, newFileName.lastIndexOf("."));
String extension = getExtension(newFileName);
Pattern pattern = Pattern.compile("( \\(\\d+\\))\\."); // Find ' (###).' in the file name, if it exists
Matcher matcher = pattern.matcher(newFileName);
String strDigits = "";
if (matcher.find()) {
baseName = baseName.substring(0, matcher.start(0)); // Remove the (###)
strDigits = matcher.group(0); // Grab the ### we'll want to increment
strDigits = strDigits.substring(strDigits.indexOf("(") + 1, strDigits.lastIndexOf(")")); // Strip off the ' (' and ').' from the match
// Increment the found digit and convert it back to a string
int count = Integer.parseInt(strDigits);
strDigits = Integer.toString(count + 1);
} else {
strDigits = "1"; // If there is no (###) match then start with 1
}
file = new File(file.getParent() + "/" + baseName + " (" + strDigits + ")" + extension); // Put the pieces back together
}
return file;
} catch (Error e) {
return originalFile; // Just overwrite the original file at this point...
}
}
private String getExtension(String name) {
return name.substring(name.lastIndexOf("."));
}
Calling getUniqueFileName(new File('/dir/example.txt') when 'example.txt' already exists while generate a new File targeting '/dir/example (1).txt' if that too exists it'll just keep incrementing number between the parentheses until a unique file is found, if an error happens, it'll just give the original file name.
I hope this helps some one needing to generate a unique file in Java on Android or another platform.
This function returns the exact new file with an increment number for all kind of extensions.
private File getFileName(File file) {
if (file.exists()) {
String newFileName = file.getName();
String simpleName = file.getName().substring(0, newFileName.indexOf("."));
String strDigit = "";
try {
simpleName = (Integer.parseInt(simpleName) + 1 + "");
File newFile = new File(file.getParent() + "/" + simpleName + getExtension(file.getName()));
return getFileName(newFile);
}
catch (Exception e){
}
for (int i=simpleName.length()-1; i>=0; i--) {
if (!Character.isDigit(simpleName.charAt(i))) {
strDigit = simpleName.substring(i + 1);
simpleName = simpleName.substring(0, i+1);
break;
}
}
if (strDigit.length() > 0) {
simpleName = simpleName + (Integer.parseInt(strDigit) + 1);
}
else {
simpleName += "1";
}
File newFile = new File(file.getParent() + "/" + simpleName + getExtension(file.getName()));
return getFileName(newFile);
}
return file;
}
private String getExtension(String name) {
return name.substring(name.lastIndexOf("."));
}

Writing GPX file to sdcard from geopoints (ArrayList)

My application tracks the distance and shows the result in km on the screen. I save the geopoints in an ArrayList. I’d like to export the geopoints as a GPX track file to my sdcard.
I tried https://sourceforge.net/projects/gpxparser/. But after the command GPXParser p = new GPXParser(); my app crashes. (I couldn’t find out how to “instantiate the GPXParser class”, maybe that’s why it didn’t work).
Importing GPX files works flawless with this approach http://android-coding.blogspot.de/2013/01/get-latitude-and-longitude-from-gpx-file.html
Could anyone point me in a direction or give me a hint. I’ve search a lot, but couldn’t find anything I could get to work.
Update!
I've found a solution. Maybe not perfect, but it works.
To save my track, I use the following from my Map-Activity.
Maybe some has a better solution :-).
public void saveRoute(String filename) {
Toast.makeText(this, mTrace.size() + "", Toast.LENGTH_SHORT).show();
String fileName = filename;
// routeFile = new File(getFilesDir(), FILENAME);
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/kml");
myDir.mkdirs();
File file = new File(myDir, fileName + ".gpx");
savegpx gpxFile = new savegpx();
try {
file.createNewFile();
gpxFile.writePath(file, fileName, mTrace);
// Log.i(TAG, "Route Saved " + file.getName());
} catch (Exception e) {
Log.e("WritingFile", "Not completed writing" + file.getName());
}
}
Separate class
public class savegpx {
private static final String TAG = savegpx.class.getName();
public savegpx() {
}
/**
* Writes locations to gpx file format
*
* #param file file for the gpx
* #param n name for the file
* #param points List of locations to be written to gpx format
*/
public static void writePath(File file, String n, ArrayList<GeoPoint> points) {
final Context applicationContext= MainActivity.getContextOfApplication();
String header = "<gpx creator=\"Off-Road Tracker\" version=\"1.1\" xmlns=\"http://www.topografix.com/GPX/1/1\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\">\n";
String metadata = " <metadata>\n" + " <time>1900-01-01T00:00:00Z</time>" + "\n </metadata>";
String name = " <trk>\n <name>" + n + "</name>\n <trkseg>\n";
String segments = "";
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
List<String> stockList = new ArrayList<String>();
for (int i = 0; i < points.size(); i++) {
stockList.add(" <trkpt lat=\"" + (points.get(i)).getLatitude() + "\" lon=\"" + (points.get(i)).getLongitude() + "\">\n <ele>" +(points.get(i).getAltitude()) + "</ele>\n <time>" + df.format(new Date()) + "Z</time>\n </trkpt>\n");
}
segments +=stockList;
segments = segments.replace(",","");
segments = segments.replace("[","");
segments = segments.replace("]","");
Toast.makeText(applicationContext, segments, Toast.LENGTH_LONG).show();
String footer = " </trkseg>\n </trk>\n</gpx>";
try {
FileWriter writer = new FileWriter(file);
writer.append(header);
writer.append(metadata);
writer.append(name);
writer.append(segments);
writer.append(footer);
writer.flush();
writer.close();
Log.i(TAG, "Saved " + points.size() + " points.");
} catch (IOException e) {
//Toast.makeText(mapsActivity.getApplicationContext(),"File not found",Toast.LENGTH_SHORT);
Log.e(TAG, "Error Writting Path", e);
}
}
}

Categories

Resources