I can't get an animated GIF animated within a CLabel. I also tried Label.
final CLabel lblSpinner = new CLabel(this, SWT.NONE);
lblSpinner.setImage(SWTResourceManager.getImage(Installation_4.class, "/resources/spinner_anim_16.gif"));
What's wrong? Only the first GIF is displayed. In RCP I have to animate programatically but in RAP this must be a job for the browser I thought.
The following snippet works with RAP, with both Label and CLabel:
public class AnimatedGifSnippet implements IEntryPoint {
public int createUI() {
Display display = new Display();
Shell shell = new Shell( display );
shell.setLayout( new GridLayout() );
Image image = createImage( display, "resources/loading.gif" );
Label label = new Label( shell, SWT.NONE );
label.setImage( image );
shell.layout();
shell.open();
return 0;
}
private Image createImage( Display display, String resourceName ) {
ClassLoader classLoader = getClass().getClassLoader();
InputStream inputStream = classLoader.getResourceAsStream( resourceName );
if( inputStream == null ) {
throw new IllegalArgumentException( "Resource not found: " + resourceName );
}
try {
return new Image( display, inputStream );
} finally {
try {
inputStream.close();
} catch( IOException exception ) {
// TODO handle exception
}
}
}
}
If this doesn't work with your image, then the problem is in the image image itself. Otherwise, you must be doing something wrong in your SWTResourceManager.getImage() method. Please note that if you construct an Image from ImageData, these will only contain a single frame of the animated gif.
Related
I am trying to check whether the text is BOXED using apache PDFBOX. for few PDF the below code wont work.
public class PDFBoxReader extends PDFGraphicsStreamEngine {
private static ArrayList<Rectangle2D> recList = new ArrayList<Rectangle2D>();
public PDFBoxReader(PDPage page) {
super(page);
}
public static boolean isTextBoxed(PDDocument document, String text) {
StingBuffer boxedText = new StringBuffer();
for (PDPage page : document.getPages()) {
PDFBoxReader reader = new PDFBoxReader(page);
try {
PDFTextStripperByArea stripper = new PDFTextStripperByArea();
rectList = new ArrayList<Rectangle2D>();
reader.processPage(page);
for (Rectangle2D react : rectList) {
Double y = page.cropBox().getUpperRightY() - rect.getY() - rect.getHeight();
rect.setRect(rect.getX(), y, rect.getWidth(), rect.getWidth(), rect.getHeight());
stripper.addRegion("box", rect);
stripper.extractRegions(page);
boxedText.append(stripper.getTextForRegion("box"));
}
if (isTextMatched(text, stripper.getTextForRegion("box"))) {
return true;
}
} catch (IoException exception) {
// exception is handled here
}
}
}
// some more methods here
}
PDF dont have any acroform. it has a paragraph in a bordered box at the end of the page.
The following is the code (using iText for.Net Version 7.0.4.0) that i am using for extracting the text from a pdf. What i have observed during my testing is it works well by only extracting the content within a rectangle for most of the pdf's. But for few of them it gives the entire line from the pdf. I know
that the text snippets that intersect with the rect (so part of the text may be outside rect, iText doesn't cut text snippets in pieces).
But I want to understand what parameter in the pdf will be used in iText to split text.
var reader = new PdfReader( filePath );
PdfDocument pdfDoc = new PdfDocument( reader );
var addressRect = new Rectangle( 33, 190, 70, 42 ); //
var addressRegionFilter = new TextRegionEventFilter( addressRect );
var filterListener = new FilteredTextEventListener( new LocationTextExtractionStrategy(), addressRegionFilter );
var addressText = PdfTextExtractor.GetTextFromPage( pdfDoc.GetPage( 1 ), filterListener );
pdfDoc.Close();
This should do the trick.
class RectangleTextExtractionStrategy implements ITextExtractionStrategy
{
private ITextExtractionStrategy innerStrategy = null;
private Rectangle rectangle;
public RectangleTextExtractionStrategy(ITextExtractionStrategy strategy, Rectangle rectangle)
{
this.innerStrategy = strategy;
this.rectangle = rectangle;
}
#Override
public String getResultantText() {
return innerStrategy.getResultantText();
}
#Override
public void eventOccurred(IEventData iEventData, EventType eventType) {
if(eventType != EventType.RENDER_TEXT)
return;
TextRenderInfo tri = (TextRenderInfo) iEventData;
for(TextRenderInfo subTri : tri.getCharacterRenderInfos())
{
Rectangle r2 = new CharacterRenderInfo(subTri).getBoundingBox();
if(intersects(r2))
innerStrategy.eventOccurred(subTri, EventType.RENDER_TEXT);
}
}
private boolean intersects(Rectangle rectangle)
{
// # TODO
return true;
}
#Override
public Set<EventType> getSupportedEvents() {
return innerStrategy.getSupportedEvents();
}
}
The idea here is to split all incoming TextRenderInfo objects into the corresponding events for their characters. Then (if they are in the search region) we delegate the call to another ITextExtractionStrategy.
Anyone can help in this code, the pdf file is not loading in app and just showing blank white screen, Logcat showing FileNotFoundExeeption: /storage/sdcard/raw/ourpdf.pdf.
i am trying to make an app that will show information while i click buttons and every button will be active for specific pdf file reading. Any specific help please.
Thanks for help
part1
package com.code.androidpdf;
public class MainActivity extends Activity {
//Globals:
private WebView wv;
private int ViewSize = 0;
//OnCreate Method:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Settings
PDFImage.sShowImages = true; // show images
PDFPaint.s_doAntiAlias = true; // make text smooth
HardReference.sKeepCaches = true; // save images in cache
//Setup above
wv = (WebView)findViewById(R.id.webView1);
wv.getSettings().setBuiltInZoomControls(true);//show zoom buttons
wv.getSettings().setSupportZoom(true);//allow zoom
//get the width of the webview
wv.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
{
#Override
public void onGlobalLayout()
{
ViewSize = wv.getWidth();
wv.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
pdfLoadImages();//load images
}
private void pdfLoadImages() {
try
{
// run async
new AsyncTask<Void, Void, Void>()
{
// create and show a progress dialog
ProgressDialog progressDialog = ProgressDialog.show(MainActivity.this, "", "Opening...");
#Override
protected void onPostExecute(Void result)
{
//after async close progress dialog
progressDialog.dismiss();
}
#Override
protected Void doInBackground(Void... params)
{
try
{
// select a document and get bytes
File file = new File(Environment.getExternalStorageDirectory().getPath()+"/randompdf.pdf");
RandomAccessFile raf = new RandomAccessFile(file, "r");
FileChannel channel = raf.getChannel();
net.sf.andpdf.nio.ByteBuffer bb = null ;
raf.close();
// create a pdf doc
PDFFile pdf = new PDFFile(bb);
//Get the first page from the pdf doc
PDFPage PDFpage = pdf.getPage(1, true);
//create a scaling value according to the WebView Width
final float scale = ViewSize / PDFpage.getWidth() * 0.95f;
//convert the page into a bitmap with a scaling value
Bitmap page = PDFpage.getImage((int)(PDFpage.getWidth() * scale), (int)(PDFpage.getHeight() * scale), null, true, true);
//save the bitmap to a byte array
ByteArrayOutputStream stream = new ByteArrayOutputStream();
page.compress(Bitmap.CompressFormat.PNG, 100, stream);
stream.close();
byte[] byteArray = stream.toByteArray();
//convert the byte array to a base64 string
String base64 = Base64.encodeToString(byteArray, Base64.DEFAULT);
//create the html + add the first image to the html
String html = "<!DOCTYPE html><html><body bgcolor=\"#7f7f7f\"><img src=\"data:image/png;base64,"+base64+"\" hspace=10 vspace=10><br>";
//loop through the rest of the pages and repeat the above
for(int i = 2; i <= pdf.getNumPages(); i++)
{
PDFpage = pdf.getPage(i, true);
page = PDFpage.getImage((int)(PDFpage.getWidth() * scale), (int)(PDFpage.getHeight() * scale), null, true, true);
stream = new ByteArrayOutputStream();
page.compress(Bitmap.CompressFormat.PNG, 100, stream);
stream.close();
byteArray = stream.toByteArray();
base64 = Base64.encodeToString(byteArray, Base64.DEFAULT);
html += "<img src=\"data:image/png;base64,"+base64+"\" hspace=10 vspace=10><br>";
}
html += "</body></html>";
//load the html in the webview
wv.loadDataWithBaseURL("", html, "text/html","UTF-8", "");
}
catch (Exception e)
{
Log.d("CounterA", e.toString());
}
return null;
}
}.execute();
System.gc();// run GC
}
catch (Exception e)
{
Log.d("error", e.toString());
}
}
}
It is (sadly) not possible to view a PDF that is stored locally in your devices. Android L has introduced the feature. So, to display a PDF , you have two options:
See this answer for using webview
How to open local pdf file in webview in android? (note that this requires an internet connection)
Use a third party pdf Viewer.
You can also send an intent for other apps to handle your pdf.
You can get an InputStream for the file using
getResources().openRawResource(R.raw.ourpdf)
Docs: http://developer.android.com/reference/android/content/res/Resources.html#openRawResource(int)
I'm trying to switch a banner adView to imageView just before I take a screenshot so that users can share this screenshot through share intent.
However, when I take the screenshot, it does not include the imageView.
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
....
adView1 = new AdView(this, AdSize.BANNER, MY_AD_UNIT_ID1);
LinearLayout.LayoutParams childParam2 = new
LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0, 0.10f);
adView1.setLayoutParams(childParam2);
adView1.loadAd(new AdRequest());
ll.addView(adView1);
setContentView(ll);
myAdView = new ImageView(this);
LinearLayout.LayoutParams childParam1 = new
LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0, 0.10f);
myAdView.setLayoutParams(childParam1);
....
View.OnClickListener handler = new View.OnClickListener() {
public void onClick(View v) {
switch (v.getId()) {
...
case R.id.menu3:
share();
break;
...
}
}
Here's share() function.
private void share(){
List<Intent> targetedShareIntents = new ArrayList<Intent>();
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("*/*");
List<ResolveInfo> resInfo =
this.getPackageManager().queryIntentActivities(intent, 0);
for (ResolveInfo resolveInfo : resInfo) {
........
if (packageName.toLowerCase().contains("twitter")){
targetedShareIntent.setType("*/*");
String location = "file://" + takeScreen(ll);
...
}
...
}
This is takeScreen(View v) function.
public String takeScreen(View c_view){
ll.removeView(adView1);
ll.addView(myAdView);
// create bitmap screen capture
Bitmap bitmap;
View v1 = c_view.getRootView();
v1.setDrawingCacheEnabled(true);
bitmap = v1.getDrawingCache();
String extr = Environment.getExternalStorageDirectory().toString();
File imageFile = new File(extr, "screen_" + System.currentTimeMillis() + ".jpg");
OutputStream fout = null;
try {
fout = new FileOutputStream(imageFile);
boolean saved = bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fout);
//Log.e("bitmap saved ?", saved + "!");
fout.flush();
fout.close();
MediaStore.Images.Media.insertImage(getContentResolver(), bitmap, "Screen", "screen");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
ll.removeView(myAdView);
ll.addView(adView1);
return imageFile.getPath();
}
As you can see, I'm removing adView and adding myAdView(imageView) just before the screenshot is taken in takeScreen() function. adView IS removed but imageVies is NOT added to the screenshot.
The imageView DOES appear on the screen just before chooserIntent(share intent) pop-up screen is displayed.
I have tried many other options like
added both views and just switched visibility. setVisibility(View.Gone, View.Visible)
tried creating bitmap with canvas instead of getDrawingCache (thinking that it could be a cache related problem)
Is taking screenshot or 'share intent' too much of work for the UI thread to be blocked?
Can anyone shed a light here? I am completely at a loss.
I found a way to get around this. I created a composite bitmap out of the background bitmap and the overlay(my ad image) bitmap. In case anyone is interested, here's the code.
public Bitmap screenShot(View view) {
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
Bitmap overlay = BitmapFactory.decodeResource(this.getResources() , R.drawable.my_ad);
canvas.drawBitmap(overlay, 100, 100, null);
return bitmap;
}
I have a custom OpenCV camera activity that takes a photo when the screen is tapped. The activity is started with a startActivityForResult intent, and the filepath of the photo is handed back to the MainActivity after the activity is finished. However, the camera saves the photo asynchronously and therefore the filepath shouldn't be checked until the photo is taken. I am using the filepath to set an imageView, and calling it immediately gives an empty image. I have managed to make it work by using Thread.sleep(3000); but this is a horrible option as it just stalls the UI which, as I've read countless times, is a big no no! Is there a way I can wait until the photo is saved before calling the return to MainActivity intent? I understand there is a callback from the camera but I don't understand how it works or how to use it, perhaps that is the best way to go?
Here's some code anyway.
in MainActivity extends FragmentActivity:
rootView.findViewById(R.id.button_start_camera).setOnClickListener(new View.OnClickListener() {
// Listen for Take Photo button Click, start app's openCV camera
#Override
public void onClick(View view) {
// Start Camera app
Intent intentCamera = new Intent(getActivity(), CameraActivity.class);
startActivityForResult(intentCamera, 2);
}
});
In CameraActivity extends Activity implements CvCameraViewListener2, OnTouchListener:
#Override
public boolean onTouch(View v, MotionEvent event) {
Log.i(TAG,"onTouch event");
if (takePicture) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HHmmss");
String currentDateandTime = sdf.format(new Date());
fileName = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getPath() +
"/MatCom_" + currentDateandTime + ".jpg";
mOpenCvCameraView.takePicture(fileName);
Toast.makeText(this, fileName + " saved", Toast.LENGTH_SHORT).show();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Intent returnIntent = new Intent();
returnIntent.putExtra("result", fileName);
setResult(RESULT_OK, returnIntent);
finish();
}
return false;
}
And then back to MainActivity:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent)
{
super.onActivityResult(requestCode, resultCode, intent);
Log.i(TAG, "onActivityResult. resultCode = " + requestCode);
if (requestCode == 1) {//My other startActivityForResult...}
if (requestCode == 131074 && resultCode == RESULT_OK){
Bundle bundle = intent.getExtras();
filepath = bundle.getString("result");
Log.i(TAG, filepath);
imageView = (ImageView) findViewById(R.id.imageView);
bmp = BitmapFactory.decodeFile(filepath);
imageView.setBackgroundResource(0);
imageView.setImageBitmap(bmp);
}
}
NOTICE: As an aside, for some reason my requestCode comes back as 131074 every time despite setting it at 2 for the startActivityForResult - let me know if you know why that is.
Finally, in case it's necessary to see, here's the takePicture method from the CameraView class:
public void takePicture(final String fileName) {
Log.i(TAG, "Taking picture");
PictureCallback callback = new PictureCallback() {
private String mPictureFileName = fileName;
#Override
public void onPictureTaken(byte[] data, Camera camera) {
Log.i(TAG, "Saving a bitmap to file");
Bitmap picture = BitmapFactory.decodeByteArray(data, 0, data.length);
try {
FileOutputStream out = new FileOutputStream(mPictureFileName);
picture.compress(Bitmap.CompressFormat.JPEG, 90, out);
picture.recycle();
// Open the image for analysis
// Read in the image from the file
Mat mOriginalImage = Highgui.imread(fileName);
// Only process the image if it actually exists!
if (mOriginalImage != null) {
// Find the size of the image
org.opencv.core.Size mSizeReadImage = mOriginalImage.size();
// From the number of rows and columns get the coordinates of the largest possible centralised square
double height = mSizeReadImage.height;
double width = mSizeReadImage.width;
double minDim = Math.min(height, width);
double top = height/2.0 - 2.0*minDim/5.0;
double left = width/2.0 - 2.0*minDim/5.0;
// Create a submat of the image based on the centralised square
Mat mOriginalImageSubmat = mOriginalImage.submat((int)Math.round(top), (int)Math.round(top + 4.0*minDim/5.0), (int)Math.round(left), (int)Math.round(left + 4.0*minDim/5.0));
// Create another Mat the required size but same type as mOriginalImageSubmat and resize mOriginalImageSubmat to fit into it
Mat mDrawableSubmat = new Mat(new Size(480.0, 480.0), mOriginalImageSubmat.type());
Imgproc.resize(mOriginalImageSubmat, mDrawableSubmat, mDrawableSubmat.size());
Mat mColourSourceSubmat = mDrawableSubmat.clone();
Mat mCannyOutput = mDrawableSubmat.clone();
double minLineLength = 300.0;
ColourMatrix matrix = new ColourMatrix();
matrix.setColourMatch(colourMatch);
matrix.setColourOrder(colourOrder);
matrix.setComparison(comparison);
matrix.setDisplayHotspots(displayHotspots);
matrix.setDisplayOutline(displayOutline);
matrix.setIntensity(intensity);
matrix.setMatrixType(matrixType);
String output = matrix.decode(mColourSourceSubmat, mCannyOutput, mDrawableSubmat, minLineLength);
Log.i(TAG, "DJH - decoded: " + output);
}
mCamera.startPreview();
} catch (Exception e) {
e.printStackTrace();
}
}
};
mCamera.takePicture(null, null, callback);
}
Thread.sleep isn't bad per se. You can use a loop to 30 with thread.sleep(100). Then you'll only be pausing .1 second at a time, and the CPU still won't spike.