Tesseract gives no recognition results (Android studio; Java) - java

I am making an app on Android Studio with tesseract OCR. I made a code which should recognize text on images taken by phone camera. Problem: tesseract function getUTF8Text() gives no result AT ALL (null, despite picture being with text). Program does not give any errors.
I wondered about possible issues: 1. Maybe I integrated tesseract into my project not properly? (Compilator does not show any issues when using tesseract classes in code) 2. Maybe problem in code? (bad traineddata path??).
Main class:
Code:
private TessOCR Tess;
//after taking picture I call:
PictureCallback pictureCallback = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
String result = Tess.getOCRResult(bitmap);
if (result != null) Log.i(TAG, result);
else Log.i(TAG, "NO RESULT");
}
};
TessOCR class for tesseract traineddata file finding or adding and text recognition (Constructor is only for finding traineddata file):
public class TessOCR {
public static final String PACKAGE_NAME = "com.example.dainius.ocr";
public static final String DATA_PATH = Environment
.getExternalStorageDirectory().toString() + "/AndroidOCR/";
public static final String lang = "eng";
private static final String TAG = "OCR";
private TessBaseAPI mTess;
public TessOCR(AssetManager assetManager) {
mTess = new TessBaseAPI();
String[] paths = new String[] { DATA_PATH, DATA_PATH + "tessdata/" };
for (String path : paths) {
File dir = new File(path);
if (!dir.exists()) {
if (!dir.mkdirs()) {
Log.v(TAG, "ERROR: Creation of directory " + path + " on sdcard failed");
return;
} else {
Log.v(TAG, "Created directory " + path + " on sdcard");
}
}
}
if (!(new File(DATA_PATH + "tessdata/" + lang + ".traineddata")).exists()) {
try {
InputStream in = assetManager.open("tessdata/" + lang + ".traineddata");
OutputStream out = new FileOutputStream(DATA_PATH
+ "tessdata/" + lang + ".traineddata");
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
Log.v(TAG, "Copied " + lang + " traineddata");
} catch (IOException e) {
Log.e(TAG, "Was unable to copy " + lang + " traineddata " + e.toString());
}
}
mTess.setDebug(true);
mTess.init(DATA_PATH, lang);
}
public String getOCRResult(Bitmap bitmap) {
mTess.setImage(bitmap);
String result = mTess.getUTF8Text();
return result;
}
public void onDestroy() {
if (mTess != null)
mTess.end();
}
If this problem is caused by bad tesseract integration, please post a proper tutorial about how to integrate it, because every tutorial on the internet is different from each other, it's hard to understand how to properly do it.

I've worked with Tesseract (tess4j). Have you tried using an image with very clear text and completely monochrome/grayscale? I've found that when I'm trying to get Tesseract to read my images it's much more useful to spend time manipulating the image trying to make it easier for Tesseract.
If you still aren't able to get it to produce output and it isn't showing any errors, I'd go here and restart the Tesseract setup with the tutorial and follow all of their tips. It shouldn't be too difficult, the .dll's are extracted and loaded automatically. Just make sure your tessdata folder is in the correct spot (root directory) and you have all the .jar's (I think there's only 4 that you need, not all of them, but check the tutorial on tess4j.sourceforge.com) as compile-time libraries.
Taken from their website: "Images intended for OCR should have at least 200 DPI in resolution, typically 300 DPI, 1 bpp (bit per pixel) monochome or 8 bpp grayscale uncompressed TIFF or PNG format." To be honest, I haven't had much luck with Tesseract besides their PDF tools to scan easy-to-read high-resolution documents.
I didn't get it to work the first time either, for what it's worth.

The cause of my problem was that I did not as permission to write external storage. If anyone will try to apply this method to extract file from assets folder (got this method from this github project), make sure you add permission to write external storage code line to your manifest (AndroidManifest.xml file):
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Related

Why is ALBUM_ART the only field that returns null from MediaStore when others are fine?

I'm having trouble retrieving the album artwork path. My storage permissions can't be the problem since I can fetch all other fields, so I'm wondering what the problem might be. I'll admit I'm a bit new to ContentResolvers and the MediaStore. I just need a path to be used in BitmapFactory.decodeFile(). The code is below, followed by the Log output.
Context (if it helps)
- Method is called from SongRoomDatabase.java (not an activity) which extends RoomDatabase.
- The context is passed from the MainActivity to the DB through the DB constructor.
Test method for retrieving album data from ALBUM_ID = 209 ("Viva la Gloria!" by Greenday)
public static void getCoverArtTest(){
Cursor cursor = mContext.getContentResolver().query(
MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
new String[] {
MediaStore.Audio.Albums._ID,
MediaStore.Audio.Albums.ALBUM,
MediaStore.Audio.Albums.ALBUM_ART,
MediaStore.Audio.Albums.ARTIST
},
MediaStore.Audio.Albums._ID+ "=?",
new String[] {String.valueOf(209)},
null);
if (cursor != null && cursor.moveToFirst()) {
String path = "";
path += cursor.getString(0) + "/";
path += cursor.getString(1) + "/";
path += cursor.getString(2) + "/";
path += cursor.getString(3) + "/";
// do whatever you need to do
Log.d("artworkTag", "Album art path: " + path);
}
}
Output
Album art path: 209/21st Century Breakdown/null/Green Day/
Is it just stored somewhere else? Do I need to retrieve it a specific way since it's not a string like the other fields (if it's returning something other than it's path)?
I noticed recently in my app the album arts started coming up empty where it had previously worked with similar code.
I checked the developer reference and there is new information about ALBUM_ART
This constant was deprecated in API level 29. Apps may not have
filesystem permissions to directly access this path. Instead of trying
to open this path directly, apps should use
ContentResolver#loadThumbnail to gain access.
So I tried changed the targetSdkVersion version back to 28 but still no good when running on a device with android 10 Q which is api 29.
So unfortunately to support newer androids we need to use something like this instead:
String filePath = null;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
Cursor albumCursor = context.getContentResolver().query(
MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Audio.Media._ID, MediaStore.Audio.Albums.ALBUM_ART},
MediaStore.Audio.Media._ID + " = " + albumId,
null,
null);
if (albumCursor != null) {
if (albumCursor.moveToFirst()) {
filePath = albumCursor.getString(1);
}
albumCursor.close();
}
} else {
Uri albumArtUri = ContentUris.withAppendedId(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, Long.parseLong(albumId));
try {
Bitmap bitmap = context.getContentResolver().loadThumbnail(albumArtUri, new Size(1024, 1024), null);
File art = new File(context.getCacheDir(), "albumart" + albumId + ".jpg");
art.createNewFile();
FileOutputStream fos = new FileOutputStream(art);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);
fos.flush();
fos.close();
filePath = art.getAbsolutePath();
} catch (IOException e) {
e.printStackTrace();
}
}

ExtentReports - screenshot not in the report - broken image

I'm trying to add a screenshot to my ExtentReport HTML file, but for some reason, the image is not there even though it DOES exist and the console shows that it's looking at the correct place (href is correct).
This is the latest trial code:
Screenshot screenshot = new AShot().shootingStrategy(ShootingStrategies.viewportPasting(1000)).takeScreenshot(driver);
String destination = getScreenshotPath();
ImageIO.write(screenshot.getImage(), "IMG", new File(destination));
test.fail("Details: " + test.addScreenCaptureFromPath(destination));
The screenshot gets saved in the destination.
When I try the debugging mode, or look at the report, it's printed as:
Details: com.aventstack.extentreports.ExtentTest#62041567
and there's a broken image under it:
As suggested - the absolute path could be a solution, but I didn't want to go that way.
I've figured out that a solution is to store the images in the same directory where the report gets generated, give the image name to .addScreenCaptureFromPath(screenshotName.PNG) and it works perfectly.
I used the absolute path
Note: inspects the broken image from the browser to validate the absolute path of the image
Take ScreenShot:
public static String TakesScreenshot(IWebDriver driver, string FileName)
{
string pathProject = AppDomain.CurrentDomain.BaseDirectory;
string pathScreen = pathProject.Replace("\\bin\\Debug", "");
string path = pathScreen + "project/Test-output/Images/";
StringBuilder TimeAndDate = new StringBuilder(DateTime.Now.ToString());
TimeAndDate.Replace("/", "_");
TimeAndDate.Replace(":", "_");
TimeAndDate.Replace(" ", "_");
string imageName = FileName + TimeAndDate.ToString();
((ITakesScreenshot)driver).GetScreenshot().SaveAsFile(path + "_" + imageName + "." + System.Drawing.Imaging.ImageFormat.Jpeg);
return path + "_" + imageName + "." + "jpeg";
}
Attach image to the report with path of the preview method:
In the specific step:
ExtentTest.Fail("message", MediaEntityBuilder.CreateScreenCaptureFromPath(TakeScreenShot.TakesScreenshot(driver, "Fatal")).Build());
With the method "TakesScreenshot" Take the screenshot
Version ExtentReport: 3,
C#,
NUnit 3
USING JAVA:
<dependency>
<groupId>com.relevantcodes</groupId>
<artifactId>extentreports</artifactId>
<version>2.41.2</version>
</dependency>
Is:
ExtentTestManager.getTest().log(LogStatus.ERROR, ExtentTestManager.getTest().addScreenCapture("//ABOLUTE/PATH/IMAGE.PNG"));
regards.
In order to get screenshot in the extent report just add a extra dot in the extent report screenshot path. Refer code below:
test.log(Status.INFO, "FAQs button clicked",
MediaEntityBuilder.createScreenCaptureFromPath("." + screenshot()).build());
Hope this helps!
You can add screenshot for absolute path as below:
File src = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
//for file copy, absolute path starts from your project directory
FileUtils.copyFile(src, new File("../resources/reports/screenshots/screen2.png"));
String img = logger.addScreenCapture("./screenshots/screen2.png");
logger.log(LogStatus.PASS, "Title verified...", img);
Please note that here in addScreenCapture() method path started from screenshots folder and not resources as in copyFile() method. Its because ExtentReports is initialized as :
ExtentReports report = new ExtentReports("../resources/reports/extentreports_v2.html", true);
so for extentreports_v2.html to find screenshot's absolute path, it should start from "reports" directory
This is will work for you as its works me as well.
public void afterScenario(Scenario scenario) throws IOException {
if (scenario.isFailed()) {
String screenshotName = scenario.getName().replaceAll(" ", "_");
//This takes a screenshot from the driver at save it to the specified location
File sourcePath = ((TakesScreenshot) testContext.getWebDriverManager().getDriver()).getScreenshotAs(OutputType.FILE);
//Building up the destination path for the screenshot to save
//Also make sure to create a folder 'screenshots' with in the cucumber-report folder
File destinationPath = new File("./src/test/resources/"+screenshotName + ".png");
//Copy taken screenshot from source location to destination location
Files.copy(sourcePath, destinationPath);
//This attach the specified screenshot to the test
Reporter.addScreenCaptureFromPath(screenshotName+".png");
System.out.println("Cant take screenshot in grid.");
}
}
I tried various sites and blogs for this issue, but couldn't get a solution anywhere. I got below solution after trying various approaches. Try the below solution and it worked perfectly for me.
public static synchronized String addScreenshots(){
WebDriver webDriver = Browser.getDriver();
Long l = Calendar.getInstance().getTimeInMillis();
String screenshotId = l.toString();
String Path = System.getProperty("user.dir")+"/ExtentReports/";
File screenshot = ((TakeScreenshot)WebDriver).getScreenshotAs(OutputType.FILE);
String imgPath = Path+screenshotId+".png";
File dest = new File(imgPath);
try {
FileUtils.copyFile(screenShot, dest);
} catch (IOException e) {
e.printStackTrace();
}
String ImagePath = "../ExtentReports/"+screenshotId+".png";
return ImagePath;
}
I tried the following code, and it resulted in a screenshot being recorded in the report.
File file = new File("./Screenshots/" + result.getName() + ".png");
String absolutePath = file.getAbsolutePath();
logger.fail("details", MediaEntityBuilder.createScreenCaptureFromPath(absolutePath).build());
The below piece of code can solve your problem:
public void reportStatus(ITestResult result){
if(result.getStatus()==ITestResult.FAILURE){
String screenshotFilePath=takeScreenshotMethod(driver, result.getName());
extentTest.log(Status.FAIL, "Screenshot", MediaEntityBuilder.createScreenCaptureFromPath(screenshotFilePath).build());
}
}
public static void TakeScreenshot(Status status, string stepDetail)
{
string path = #"C:\ExtentReports\" + "TestExecLog_" + DateTime.Now.ToString("yyyyMMddHHmmss");
Screenshot image = ((ITakesScreenshot)driver).GetScreenshot();
image.SaveAsFile(path + ".png", ScreenshotImageFormat.Png);
ExtentReport.exChildTest.Log(status, stepDetail, MediaEntityBuilder.CreateScreenCaptureFromPath(path + ".png").Build());
}
public static void ReadJsonObject(string filename)
{
string myJsonString = File.ReadAllText(#"..\\..\\..\\" + filename);
jobject = JObject.Parse(myJsonString);
}
public static void ReadJsonArray(string filename)
{
string myJsonString = File.ReadAllText(#"..\\..\\..\\" + filename);
jarray = JArray.Parse(myJsonString);
}

Create a video preview image like youtube or whatsapp from a Video file (.mp4) using JAVA Code

Issue 1. When I use FFmpeg Java api, program doesn't run and print anything after grabber.start(). No preview generated.
Code Sample :
public static boolean generatePreviewImage(String filePath, String previewFileName ) throws IOException {
boolean isPreviewGenerated = false;
System.out.println("Request received to generate thumbnail for video.");
System.out.println("VideoFilePath : "+filePath);
System.out.println("ResultFileName : "+previewFileName);
try {
FFmpegFrameGrabber fGrabber = new FFmpegFrameGrabber(filePath);
System.out.println("FrameGrabber found "+fGrabber);
fGrabber.start();
System.out.println("Frame started..");
ImageIO.write(fGrabber.grab().getBufferedImage(), "jpg", new File(previewFileName));
System.out.println("Image written successfully as "+previewFileName);
isPreviewGenerated = true;
fGrabber.stop();
System.out.println("FrameGrabber stopped.. "+fGrabber);
} catch(Exception e){
System.out.println("Exception while creating video thumbnail : "+previewFileName+" - exception - "+e);
e.printStackTrace();
}
System.out.println("Image written successfully? "+previewFileName);
return isPreviewGenerated;
}
Result :
Request received to generate thumbnail for video.
VideoFilePath : /root/appdir/VIDEO20171124143855.mp4
ResultFileName : /root/appdir/vdthumb_0.jpg
FrameGrabber found org.bytedeco.javacv.FFmpegFrameGrabber#3529360e
Nothing happens and gets printed after above statement..
Additional Information :
I installed FFmpeg on Linux VPS as well and able to generate preview using command line
root#vps19984[~/usr/appdir]#ffmpeg -i /root/appdir/.VIDEO20171123165555.mp4 -r 1 -f image2 image-%2d.png
(above command ffmpeg generates preview successfully on linux box but I want to generate it via Java program)
Issue 2. When I use JCodec api, program generates a black image but NOT an image from video file.
Code Sample :
public static boolean generatePreviewImage(String filePath, String previewFileName ) throws IOException, JCodecException {
logger.info("Request received to generate thumbnail for video. VideoFilePath : "+filePath+", resultFileName "+previewFileName);
boolean isPreviewGenerated = false;
Picture framePic = FrameGrab.getNativeFrame(new File(filePath),20);
logger.info("Frame grabbed successfully..");
Transform transform = ColorUtil.getTransform(framePic.getColor(), ColorSpace.RGB);
Picture rgb = Picture.create(framePic.getWidth(), framePic.getHeight(), ColorSpace.RGB);
transform.transform(framePic, rgb);
logger.info("Frame transformed successfully to RGB..");
BufferedImage dst = new BufferedImage(rgb.getCroppedWidth(), rgb.getCroppedHeight(),
BufferedImage.TYPE_INT_RGB);
ImageIO.write(dst, "jpg", new File(previewFileName));
isPreviewGenerated = true;
logger.info("Is preview generated.."+isPreviewGenerated);
}
Result :
Request received to generate thumbnail for video. VideoFilePath : /usr/appdir/VIDEO20171123165555.mp4, resultFileName /usr/appdir/vdthumb_0.jpg
Frame grabbed successfully..
Frame transformed successfully to RGB..
Is preview generated..true
Issue : A black jpg image of 5 KB gets generated by JCodec
Check this code, as it successfully creates the file. Have made a few changes.This is the solution for Issue1.
If you are unable to see the logs, then the issue is with the logger. You can paste the logger you are using or google the issue with your logger.
public static boolean generatePreviewImage(String filePath,
String previewFileName) throws IOException, Exception {
logger.info("Request received to generate thumbnail for video. VideoFilePath : "
+ filePath + ", resultFileName " + previewFileName);
boolean isPreviewGenerated = false;
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(filePath);
logger.info("FrameGrabber found " + grabber);
grabber.start();
logger.info("FrameGrabber started.. " + grabber);
for (int i = 20; i < 22; i++) {
logger.info("Reading first 2 images..");
ImageIO.write(grabber.grab().getBufferedImage(), "jpg", new File(
previewFileName + "_" + i));
logger.info(i + " image written successfully as " + previewFileName
+ "_" + i + ".jpg");
isPreviewGenerated = true;
}
grabber.stop();
logger.info("Is preview generated.." + isPreviewGenerated);
return isPreviewGenerated;
}
Thanks Urvashi for all your comments and suggestion. With FFMpeg, things are not working on my environment. I am not getting any exception either. I will try futher and see what is the issue.
But with JCodec (Issue no. 2) I am able to generate the preview with following code:
In pom.xml added following two dependencies:
<dependency>
<groupId>org.jcodec</groupId>
<artifactId>jcodec</artifactId>
<version>0.2.2</version>
</dependency>
<dependency>
<groupId>org.jcodec</groupId>
<artifactId>jcodec-javase</artifactId>
<version>0.2.1</version>
</dependency>
And in java file written following code:
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.jcodec.api.JCodecException;
import org.jcodec.api.awt.AWTFrameGrab;
public static boolean generatePreviewImage(String filePath, String previewFileName ) throws IOException, JCodecException {
boolean isPreviewGenerated = false;
try {
double sec = 1;
BufferedImage dst = AWTFrameGrab.getFrame(new File(filePath), sec);
ImageIO.write(dst, "jpg", new File(previewFileName));
isPreviewGenerated = true;
//where filePath is the path of video file and previeFileName is the name of preview image file.
} catch(Exception e) {
System.out.println("Exception while creating video thumbnail : "+previewFileName+" - exception - "+e);
e.printStackTrace();
}
System.out.println("Image written successfully? "+previewFileName);
return isPreviewGenerated;
}
Thanks!

Delete image thumbnail from gallery when it got hidden

this question has been asked before(not specifically like this) but there hasn't been an All Exclusive answer to it yet. so we are trying to find the best solution here. i'm developing an app and in my app i hide a directory named myPic by moving it's files to a directory called .myPic. when i hide my pictures it's thumbnails are still in gallery. i find 3 solution to this:
first solution:
using ACTION_MEDIA_MOUNTED broad cast like this:
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
the problem with this code is that it takes hug resources and most importantly it is blocked since android 4.4. so using this method is not rational for adding 10 pictures to gallery. so it is not an All exclusive method. also using ACTION_MEDIA_SCANNER_SCAN_FILE doesn't work on android 4.4 either
second solution:
using MediaScannerConnection. so i created a for loop and pass the old address of every file that i hide. this is my MediaScannerConnection function:
private void scanFile(File file) {
// Tell the media scanner about the new file so that it is
// immediately available to the user.
MediaScannerConnection.scanFile(this,new String[] { file.toString() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
}
the thing about MediaScannerConnection is that it only effect if the file exist. so lets say i have a picture called 1.jpg in myPic directory. using this class i can add 1.jpg to my gallery immediately but when i move 1.jpg to .myPic directory and i scan the old path of 1.jpg nothing happen. logcat says that this file doen't exsit. so MediaScannerConnection only add files to gallery. what if i pass the new path of 1.jpg to MediaScannerConnection? well it adds 1.jpg from .myPic directory to gallery and that is exactly not what i want. so again not an All Exclusive method
third solution:
using getContentResolver(). so for deleting thumbnails this method may be the ultimate solution. so i write the blow code. in every loop i retrieve the path of image and pass it to getContentResolver().delete(Uri.parse(path),null,null). here is the code:
File myPic = new File(Environment.getExternalStorageDirectory()+"/myPic");
File myPicHide = new File(Environment.getExternalStorageDirectory()+"/.myPic");
if (!(myPicHide.exists()) & !(myPicHide.isDirectory())) {
myPicHide.mkdirs();
};
if (myPic.isDirectory()) {
String[] childeren = myPic.list();
if (childeren.length > 0) {
for (int i = 0; i < childeren.length; i++) {
String fileName = childeren[i];
File from = new File(Environment.getExternalStorageDirectory()+"/myPic"+fileName);
File to = new File(Environment.getExternalStorageDirectory()+"/.myPic"+fileName);
from.renameTo(to);
try {
String path = from.toString();
getContentResolver().delete(Uri.parse(path),null,null);
} catch(Exception e) {
Log.d("Rename", "Error happened");
}
}
}
} else {
Toast.makeText(getApplicationContext(), "myPic directory not found", Toast.LENGTH_LONG).show();
}
but it's not working either and thumbnails of my files are still showed in galley. so am i using getContentResolver() in wrong way?? this might be the all Exclusive method for the situation where deleted files thumbnails show up in gallery. i have my files path and i need to only delete it from media store content provider.
update:
so turns out that using Uri.parse(path) in the third solution is wrong. image Uri is started with content:// and it can be retrieved by MediaScannerConnection. so i created a Uri called imageInGalleryUri and assign null value to it. using my scanFile function i changed it's value from time to time and pass it's value to getContentResolver(). here is the code:
boolean whereIsMediaState = true;
Uri imageInGalleryUri = null;
File myPic = new File(Environment.getExternalStorageDirectory()+"/myPic");
File myPicHide = new File(Environment.getExternalStorageDirectory()+"/.myPic");
if (!(myPicHide.exists()) & !(myPicHide.isDirectory())) {
myPicHide.mkdirs();
};
if (myPic.isDirectory()) {
String[] childeren = myPic.list();
if (childeren.length > 0) {
for (int i = 0; i < childeren.length; i++) {
String fileName = childeren[i];
File from = new File(Environment.getExternalStorageDirectory()+"/myPic"+fileName);
scanFile(from);
File to = new File(Environment.getExternalStorageDirectory()+"/.myPic"+fileName);
from.renameTo(to);
if (to.isFile()){
try {
getContentResolver().delete(imageInGalleryUri,null,null);}
catch(Exception e) {
Log.d("Rename", "Error happened");
}
}
}
} else {
Toast.makeText(getApplicationContext(), "myPic directory not found", Toast.LENGTH_LONG).show();
}
private void scanFile(File file) {
// Tell the media scanner about the new file so that it is
// immediately available to the user.
MediaScannerConnection.scanFile(this,new String[] { file.toString() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
imageInGalleryUri = uri;
}
});
}
i tried the code but it only detect the first image and delete it from the gallery but does not effect the other images. i can't figure out why. any idea?
thank you for your help in advance
. before folder just make it invisible. But there is way to say don't use this folder at all to gallery.
Please try to put empty file called ".nomedia" file into your folder.

My working directory, files, and urls

I have a convergence of needs revolving around where my data files are. The current application has all class and data files in a JAR (building using Eclipse IDE).
I've noticed there seem to be a variety of ways in which people get this information. I need the path for where my image files are (graphics). I also need it as a URL o use the toolkit call.
Toolkit tk = frame.getToolkit();
image = tk.getImage(url.toFile());
But I am having trouble with creating the URL or something. I have tried a few different methods. At this point, I keep data files next to class files in the file system. I am adding another function to what I do - strip the /bin directory off when running in debug.
// in class BwServices at init:
try {
rootDataPath = BwServices.class.getProtectionDomain()
.getCodeSource().getLocation().getPath();
rootDataPath = URLDecoder.decode(rootDataPath, "UTF-8");
fileSystemAccess = true;
}
if(rootDataPath.endsWith("/bin/"))
rootDataPath = rootDataPath.substring(0, rootDataPath.length() - 4);
Later on... I go to get images, and some calls don't work, I don't know why
I've tried two things....
// 1
String s = "file://" + rootDataPath + d.toString() + fileName;
url = frame.getClass().getResource(s);
// 2
try {
url = new URL(s);
} catch (MalformedURLException e) {
trace("getImage - can't get url: " + s);
e.printStackTrace();
}
Either of which has problems.
I have calls to get images from different places. The 'frame' is the parent frame throughout the execution, in class BwFrame.
My path comes out like this in any attempts...
rootDataPath: /C:/Users/Markgm/Documents/DEV/workspace/bwp/
So, I'm looking for ways to open either FileInputStream or URLs for the toolkit, for files relative to where the class file is (and with some trick for when in debug). For a client-side app this is what this is. Someday, I might want to run this as an Applet, but I don't know where the image files will have to be. (50x75 playing cards and a few button images) Any help or advice is appreciated!
TIA,
Mark
Toolkit tk = frame.getToolkit();
Don't use Toolkit to load images, since Java 1.4. Use ImageIO.read(String/File/URL) instead, which is a blocking method that ensures the entire image is loaded before returning.
image = tk.getImage(url.toString());
And there is an actual problem. Once you have an URL (or File) object, don't toss it away and use the String representation. Even more importantly, don't provide a String that is supposed to represent a File, but actually represents an URL!
I didn't read the rest of that mess of code snippets (in the question or follow-up 'answer'), you might look to post an SSCCE in future.
I got rid of using URLs at all, which started with the use of pasted code. The behavior of URLs changed, as did everything, when running from a class file versus running from a JAR file. So I have code here that shows some of what I ended up doing, and comments to what happens (class file or jar file), and I also got the adjustment for debug time to work (snipping off bin/ from the end).
// root path - starts with jar file or pathspec
try {
rootDataPath = BwServices.class.getProtectionDomain()
.getCodeSource().getLocation().getPath();
rootDataPath = URLDecoder.decode(rootDataPath, "UTF-8");
if(rootDataPath.endsWith("BwPlayer.jar"))
rootDataPath = rootDataPath.substring(0, rootDataPath.length() - 12);
fileSystemAccess = true;
} catch(SecurityException e) {
trace("No file system access: " + e.getMessage());
messageBox(frame, "BwServices", "Cannot access file system");
rootDataPath = "";
} catch (UnsupportedEncodingException e) {
trace("Jar URL decode exception: "+ e.getMessage());
}
if(rootDataPath.endsWith("/bin/")) // remove bin/ portion if in debug
rootDataPath = rootDataPath.substring(0, rootDataPath.length() - 4);
trace("rootDataPath: "+rootDataPath);
Above: from init() time. Below, a getImage() function, including extra debug-related lines. Note: url.getFile() doesn't directly work for 2 reasons - one is it has the file:/ when out of a jar, and the other because it won't take a full pathspec beneath its pre-stated root /.
static public Image getImage(Directory d, String fileName) {
Image image = null;
String s = d.toString() + fileName;
/*
// Note: Start with / required for this url call (w/o full pathsepc)
URL url = parentFrame.getClass().getResource("/" + s);
if(url == null) {
trace(s + " - null url ");
return null;
}
*/
String file = rootDataPath + s; // url.getFile();
// end note
String t = s = "getImage(" + file + ") ";
Toolkit tk = parentFrame.getToolkit();
if(tk == null)
s = s + "NULL tk ";
else {
try {
// full pathspec needed here
// url.getFile() returns with file:/ when running from the .jar file
// but not when running from .class file (so don't use it)
s = t = "getImage(" + file + ") ";
image = tk.getImage(file); //url.getFile());
MediaTracker media = new MediaTracker(parentFrame);
media.addImage(image, 0);
try {
media.waitForID(0);
} catch(InterruptedException e) {
s = s + e.getMessage();
}
if(image == null) {
// image = null;
s = s + "NULL image ";
} else if(image.getHeight(parentFrame) < 1) {
s = s + "invalid height";
}
} catch (SecurityException e) {
s = s + e.getMessage();
}
}
if(! s.equals(t)) {
s = "file=" + file + "\n" + s;
s = "rootDataPath=" + rootDataPath + "\n" + s;
messageBox(parentFrame, "getImage()", s);
}
return image;
}

Categories