Bitmap collision detection - android

I'm trying to make my app detect when two bitmaps intersect each other. This is the code I tried for collision:
//width and height of the two bitmaps
int width1 = bplay1.getWidth();
int height1 = bplay1.getHeight();
int width2 = bbrick1.getWidth();
int height2 = bbrick1.getHeight();
if (height1 < height2)
if ( width1 < width2)
{
currentscore.setText("collision detected");
}
However, the app crashes on start when I use getHeight() and getWidth(). Am I doing something wrong with it?

If it crashes, what output does it generate in the crash (in logcat)?
Assuming it crashes with null pointer exception (which to me seems most likely based on the very terse information you provided), you should make sure your bplay1 and/or bbrick1 objects are not null like so: bplay1 = new MyClass();
Summary: Whenever you post a S.O. question ask yourself this: If I found this post, what information would I be likely to need to solve it? In this specific case there is actually very little to go on.

Related

Prevent Android's TextView from breaking links

This question is probably the same as this one, but since none of its answers really solve the problem, I'll ask again.
My app has a TextView that occasionally will display very long URLs. For aesthetic reasons (and since the URLs contain no spaces), the desirable behaviour would be to fill each line completely before jumping to the next one, something like this:
|http://www.domain.com/som|
|ething/otherthing/foobar/|
|helloworld |
What happens instead, is the URL being broke near the bars, as if they were spaces.
|http://www.domain.com/ |
|something/otherthing/ |
|foobar/helloworld |
I tried extending the TextView class and adding a modified version of the breakManually method (found here) to trick the TextView and do what I need, calling it on onSizeChanged (overridden). It works fine, except for the fact that the TextView is inside a ListView. When this custom TextView is hidden by the scrolling and brought back, its content goes back to the original breaking behaviour, due to the view being re-drawn without onSizeChanged being called.
I was able to work-around this problem by calling breakManually inside onDraw. This presents the expected behaviour at all times, but at a high performance cost: since onDraw is called whenever the ListView is scrolled and the breakManually method isn't exactly "lightweight", the scrolling gets unacceptably laggy, even on a high-end quad-core device.
Next step was to crawl through the TextView source code, trying to figure where and how it splits the text, and hopefully override it. This was a complete failure. I (a newbie) spent the whole day fruitlessly looking at code I mostly couldn't understand.
And that brings me here. Can someone please point me the right direction about what I should override (assuming that it's possible)? Or maybe there is a simpler way of achieving what I want?
Here's the breakManually method I mentioned. Due to the use of getWidth(), it only works if called after the view is measured.
private CharSequence breakManually (CharSequence text) {
int width = getWidth() - getPaddingLeft() - getPaddingRight();
// Can't break with a width of 0.
if (width == 0) return text;
Editable editable = new SpannableStringBuilder(text);
//creates an array with the width of each character
float[] widths = new float[editable.length()];
Paint p = getPaint();
p.getTextWidths(editable.toString(), widths);
float currentWidth = 0.0f;
int position = 0;
int insertCount = 0;
int initialLength = editable.length();
while (position < initialLength) {
currentWidth += widths[position];
char curChar = editable.charAt(position + insertCount);
if (curChar == '\n') {
currentWidth = 0.0f;
} else if (currentWidth > width) {
editable.insert(position + insertCount , "\n");
insertCount++;
currentWidth = widths[position];
}
position++;
}
return editable.toString();
}
To everyone who bothered reading this, thanks for your time.
If you're not using a monospace font, then in some cases it's not even possible to align it very well. Since you have no whitespaces in a URL, it's not likely that a Justify-like alignment will solve the problem. I suggest that you use a monospace font for that particular TextView. Then, decide on a fixed number of characters per line and break the string to display with "\n" after those many characters.
This isn't answering your question but it's the smoothest way possible, I guess.

refreshing of canvas is happening only after touch

I am using ViewPagerparallax class,(for parallax view ) and I am setting the background using pager.setbackgroundAsset(....);
everything works fine....but I have a situation,what i want to achieve is that whenever the fragments go in a pause state and whenever it is resumed,the background should change and hence i am changing the background in the onResume method but seems like change is only visible whenever i try to swipe between fragments ...
this is my code
public void onResume()
{
Activity_Fragments ab = (Activity_Fragments) this.getActivity();
ViewPagerParallax pager=ab.hi();
int arr[]={R.raw.a1,R.raw.a2,R.raw.a3,R.raw.a4,R.raw.a5,R.raw.a6,R.raw.a7,R.raw.a8,
R.raw.a9,R.raw.a10,R.raw.a11,R.raw.a12,R.raw.a13,R.raw.a14,R.raw.a15,R.raw.a16,
R.raw.a17,R.raw.a18,R.raw.a19,R.raw.a20,R.raw.a21,R.raw.a22,R.raw.a23,
R.raw.a24,R.raw.a25,R.raw.a26,R.raw.a27,R.raw.a28,R.raw.a29};
int x=(int)(Math.random() * ((28 ) + 1));
pager.setBackgroundAsset(arr[x]);
A few notes.
First of, I am assuming you are using this: https://github.com/MatthieuLJ/ViewPagerParallax/blob/master/src/com/matthieu/ViewPagerParallax.java
When looking at the source it appears to be that you are doing things correctly.
I few things I can see that could be happening
The max number of pages set is 0, which is the default
The width or height is 0
The background hasn't changed from last time
The application has run out of memory (They say they don't want to use more then 1/5th of the memory
An exception was thrown while creating the bitmap of the image
A few things you could try
For point number 1, if you haven't already, call the set_max_pages with a number you see fit.
Point 2, Is the ViewPager in the activity with width and height set?
Point 3, confirm that you generator is working. (Already done, logic works perfect)
int arr[]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,
18,19,20,21,22,23,24,25,26,27,28,29};
for(int i = 0; i < 100; i++){
Log.d("TEST", String.valueOf(arr[(int)(Math.random() * ((28 ) + 1))]));
}
This returns the desired output, no problem there.
Point 4 & 5, Check logcat, it could say some errors, the tag should say ViewPagerParallax
I would say point 1 could be it, it will draw the background if it hasn't already once you set it.
I'm not really sure how setBackgroundAsset works, but try a call to invalidate(); at the end of onResume(). That will insure that your onDraw() method will be called ASAP and the new background will be redrawn.

Template Matching for android-opencv application

I have developed an algorithm for android using OpenCV. I need to find overlap between the previous image and current frame. So, I have produced the template from previous image to match with current frame to make a photograph. It is the procedure to complete photographing. (Taking more than 10 picture)
Here is the code that I have developed to find the overlap.
public void overlapFinder(Mat inputFrame , Mat inputTemplate )
{
Mat mResult;
int resultWidth = inputFrame.width() - inputTemplate.width() + 1;
int resultHeight = inputFrame.height() - inputTemplate.height() + 1;
mResult = new Mat(resultHeight, resultWidth, CvType.CV_8U);
Imgproc.matchTemplate(inputFrame, inputTemplate, mResult,Imgproc.TM_CCORR_NORMED) ;
Core.MinMaxLocResult result = Core.minMaxLoc(mResult);
#SuppressWarnings("unused")
double maxVal = result.maxVal;
}
The problem is that when the "overlap function" is called after generating template from previous image, the application is crashed.
Would anyone please help me with that?
Thanks
Maybe you really need to do some debugging first, but in any case, I can see from your code that it would be worthwhile checking the sizes of your images - it seems that your code assumes the template is always smaller than the input frame.
If that's not true, you will get negative resultWidth and/or resultHeight, which will make it crash.
One other thing - the documentation suggests that the result type should be CV_32FC1.
PS - Try initialising your result like this:
mResult.create(resultHeight, resultWidth, CvType.CV_32FC1);

Is there a way to tell if a Bitmap has been completely disposed on Android?

I am creating a viewer application that calls BitmapRegionDecoder.decodeRegion(Rect, BitmapFactory.Options). I am disposing of the bitmap previously got from decodeRegion before each call:
//this is a function I wrote that gets the rectangle I need
//from the zoom/pan state of a lower-resolution ImageView (page).
//it is bragable.
Rect areaRect = page.getBitmapRegionDecoderRect(areaBitmapRect);
BitmapFactory.Options options = new BitmapFactory.Options();
//area is the ImageView which will get the hi-res bitmap in it.
if(area.getHeight()!=0)
{
//I used Math.round because we are so desperate to save memory!
//The consequent blurring is actually not too bad.
options.inSampleSize = Math.round( ((float) areaRect.height()) / ((float) area.getHeight()) );
}
else
{
options.inSampleSize = Math.round( ((float) areaRect.height()) / ((float) page.getHeight()) );
}
if(options.inSampleSize==0) options.inSampleSize=1;
if(options.inSampleSize>16) options.inSampleSize=16;
options.inPreferredConfig = Bitmap.Config.RGB_565;
if(areaRect.left<0) areaRect.left = 0;
if(areaRect.right>areaBitmapRect.right) areaRect.right = areaBitmapRect.right;
if(areaRect.top<0) areaRect.top = 0;
if(areaRect.bottom>areaBitmapRect.bottom) areaRect.bottom = areaBitmapRect.bottom;
if(areaBitmap!=null)
{
//recycling our garbage ... or are we?
areaBitmap.recycle();
areaBitmap = null;
try
{
//dirty hack
wait(200);
}
catch(Exception x)
{
//something happened.
}
}
//the all-important call
areaBitmap = areaDecoder.decodeRegion(areaRect, options);
area.setImageBitmap(areaBitmap);
I was having problems with the fact that on very quick successive UI events, we were running out of memory. As you can see I have "solved" this with the dirty hack (the thread waits 200ms and gives Android a bit of time to catch up).
I'm not very happy with this, for obvious reasons. Firstly, is my diagnosis (that garbage collection is not finishing before we allocate new memory) correct? Secondly, I tried putting
while(!areaBitmap.isRecycled())
around a counter increment after the recycle() call and the counter stayed at zero. I see the sense in having isRecycled() do this but I need something like an isCompletelyRecycled() method instead. Does Android have anything like this? Thirdly, if I can't get anywhere with this, is there an "available memory" method I can use to tell if my call is going to push us over? I can't find one. It would be nice if Android would say MORE CORE AVAILABLE BUT NONE FOR YOU so I could maybe call my wait loop as a plan B, or eventually try something less intensive instead.
Bitmap memory is allocated in the native heap, so System.gc() will not help. The native heap has its own GC, but clearly it is is not kicking in quickly enough for you - and I am not aware of any way to force it (ie there is not a native analogue of System.gc()).
You could change the structure of your application as Nicklas A suggests to re-use your bitmap.
Or you could use the native heap monitoring mechanisms detailed in BitmapFactory OOM driving me nuts to determine when it is safe to allocate a new bitmap.
Try running System.gc() instead of the sleep.
Actually I'm unsure if this will help as bitmap seems to be mostly native code meaning that it should be released as soon as recycle is called.
To me it seems like creating a new bitmap on every UI event seems like a bad idea, couldn't you just create one bitmap and edit that one?

Obtaining SurfaceView dimensions

I think I might be about to ask a dummy question, but I'm still new with Android programming, and I couldn't (despite all my efforts) find my answer on Google.
The thing is, I'm trying to develop a little game, with 2D Graphics. I want my "gaming board" to be at a specific position on my screen, so that I can display in-game informations above and below the box. But since there is beginning to be a lot of Android phones out there, I was thinking about getting "dynamic" values so that I can adapt my font size to every device.
My game is not in full screen (but it could be, it's no big deal), but in a window with no title bar.
I'm using an extension of the default SurfaceView class, implementing SurfaceHolder.Callback. I tried writing the following method :
public void getViewSize()
{
VIEW_WIDTH = this.getWidth();
VIEW_HEIGHT = this.getHeight();
}
but the values returned are zeroes.
Anyone got an idea (even if it means changing display strategy) ?
Thanks a lot.
You can do this:
public void onDraw(Canvas canvas) {
VIEW_WIDTH = canvas.getWidth();
VIEW_HEIGHT = canvas.getHeight();
}

Categories

Resources