Canvas transform issue in Firefox on nexus7 - android

var targetSize = Math.max($(window).width(), $(window).height());
var canvas = $("#canvas")[0];
canvas.setAttribute('width', $(window).width());
canvas.setAttribute('height', $(window).height());
var context = canvas.getContext("2d");
var img = new Image(); // Create new img element
img.onload = function () {
angle = Math.PI / 4;
context.setTransform(1, 0, 0, 1, 0, 0); //attempt to reset transform
context.drawImage(img, 0, 0);
};
img.src = '../../Images/FloorPlans/GroundFloor.jpg'; // Set source path
This code produces the first image below on firefox17 on my nexus7. The original image is NOT angled, all of the lines should be north-south and east-west. It appears correctly on Firefox and chrome on the desktop, and chrome on my nexus7.
If i try to "un-skewer" the image using...
context.setTransform(1, 0, Math.tan(angle), 1, 0, 0);
I get the second output below! My target platform has to be FF on the Nexus7 :(
How can this be fixed? Or is this a firefox bug?

I've kinda worked it out.
The original image was a jpg, 1859px * 1568px ~ 501kb.
I resized it down to 50% and it worked! I then went back to the full size image (still not working) before resizing down 5% at a time. All of the images failed until I got to 75% of the original size (1394px * 1176px ~ 342kb) which worked perfectly!
So, the issue is either one of image size or file size.
Happy hunting!
UPDATE!
Thanks to Edward Falk's comment below, we have a definitive answer. Yes, shaving a single pixel of of the width of the image (thus making the width an even number of pixels) fixed the problem entirely.
Firefox canvas requires (some?) images to have an even pixel width and height, otherwise they may render incorrectly.

Related

Thresholding in Android using opencv

Not sure if this is the right way to ask, but please help. I have an image of a dented car. I have to process it and highlight the dents and return the number of dents. I was able to do it reasonably well with the following result:
The matlab code is:
img2=rgb2gray(i1);
imshow(img2);
img3=imtophat(img2,strel('disk',15));
img4=imadjust(img3);
layer=img4(:,:,1);
img5=layer>100 & layer<250;
img6=imfill(img5,'holes');
img7=bwareaopen(img6,5);
[L,ans]=bwlabeln(img7);
imshow(img7);
I=imread(i1);
Ians=CarDentIdentification(I);
However, when I try to do this using opencv, I get this:
With the following code:
Imgproc.cvtColor(source, middle, Imgproc.COLOR_RGB2GRAY);
Imgproc.equalizeHist(middle, middle);
Imgproc.threshold(middle, middle, 150, 255, Imgproc.THRESH_OTSU);
Please tell me how can I obtain better results in opencv, and also how to count the dents? I tried findcontour() but it gives a very large number. I tried on other images as well, but I'm not getting proper results.
Please help.
So you basically from the MATLAB site, imtophat does - Top-hat filtering computes the morphological opening of the image (using imopen) and then subtracts the result from the original image.
You could do this in OpenCV with the following steps:
Step 1: Get the disk structuring element
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (15, 15))
Step 2: Compute opening of the image and then subtract the result from the original image
tophat = cv2.morphologyEx(v, cv2.MORPH_TOPHAT, kernel)
This gives following result -
Step 3 - Now you could just manually threshold it or use Otsu -
ret, thresh = cv2.threshold(tophat, 17, 255, 0)
which gives you the following image -
Since the OP wants the code in Java, here is the probable code in Java:
private Mat topHat(Mat image)
{
Mat element = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(15, 15), new Point (0, 0));
Mat dst = new Mat;
Imgproc.morphologyEx(image, dst, Imgproc.MORPH_TOPHAT, element, new Point(0, 0));
return dst;
}
Make sure you do this on a gray scale image (CvType.8UC1) and then you can threshold suitably.

Android: FBO to Bitmap. Scrambled result with NPOT image sizes on some devices

Honestly, I don't like to ask things this way, but I have no clue about this one!
Have you seen this before??
It can be seen that the image is scrambled following some defined pattern. This happens only in some (low end) devices, with Non Power of two images (FBO). It works well on other devices.
What I do, is to load an Android Bitmap to a FBO (works OK, as it shows ok on the screen). I do some editing (I paste a sticker, which in the image seems to be in the right place), and finally save the FBO into a Bitmap again. It works ok for a 512x512 FBO (the FBO has the image size), but no for that one (507x800).
Any Ideas??? I don't post code because I have no clue, please tell me and I'll add it.
This is the GL call to retrieve info from FBO
public Buffer toPixelBuffer(){
final int w = this.getWidth(); //colorTexture width
final int h = this.getHeight();
final ByteBuffer pixels = BufferUtils.newByteBuffer(w*h * 4);
Gdx.gl.glPixelStorei(GL10.GL_PACK_ALIGNMENT, 1);
Gdx.gl.glReadPixels(0,0, w, h, GL20.GL_RGBA, GL20.GL_UNSIGNED_BYTE, pixels);
pixels.clear();
return pixels;
}
I also don't have a buggy device with me to test right now :(
Thank you!
I had the exact same problem. I experienced this on Galaxy Ace, Galaxy Y, and some other devices.
After lot of testing I did found out that it wasn't even required POT textures, so keeping the texture size with a 64 pixel increment made the trick. So lets say if I have a 122x53 texture, I need to convert it to 128x64. An so on.
Next is the function I use to get a valid texture dimension. Call it for both Width and Height.
/**
* Some GPUs such as the "VideoCore IV HW" on the Samsung Galaxy Ace
* require texture (FBO) sizes to be in '64' increments (WTF!!!!)
*
* #param dimension
* Base dimension to calculate
* #return Resolved 64 dimension
*/
public static int calculate64Dimension(final int dimension)
{
return (((dimension - 1) >> 6) << 6) + 64;
}

Big bitmap not always created

everybody!
I draw a plot based on some data in my app. The plot is with scrolling and zooming. I create 2 bitmaps for this purpose in MyMainFragment.onActivityCreated().
if (bitmaps[0] != null)
{
return;
}
final int deviceWidth = getResources().getDisplayMetrics().widthPixels;
final int deviceHeight = getResources().getDisplayMetrics().heightPixels;
final int deviceMaxDim = Math.max(deviceHeight, deviceWidth);
bitmaps[0] = Bitmap.createBitmap(
deviceMaxDim * 2,
deviceMaxDim * 1,
Bitmap.Config.ARGB_8888);
bitmaps[1] = Bitmap.createBitmap(
bitmaps[0].getWidth(),
bitmaps[0].getHeight(),
bitmaps[0].getConfig());
I need 2 bitmaps and not only 1 because of the drawing algorithm I use. Running the program on Asus Transformer, the bmp size in pixels is 1280 * 2 * 1280, thus the byte size being 1280 * 2 * 1280 * 4. When I run the program from Eclipse, everything's fine. But when I launch it like an ordinary user from the tablet, it crashes every second time.
What's happening behind the scene when I launch my app from Eclipse that allows it to run and can I follow the same steps programmatically so that it doesn't crash when launched normally? Or should I use some other drawing algorithms (maybe something like OpenGL)?
Thanks a lot.
The solution was simple. I created a Canvas somewhere in my code, called Canvas#setBitmap(bitmaps[?]) on it, but didn't realise, that I must call Canvas.setBitmap(null) to free the reference.

Android getPixels() possibly a silly mistake?

Okay, this is quite simple to understand, but for some bizarre reason I can't get it working.. I've simplified this example from the actual code.
InputStream is = context.getResources().openRawResource(R.raw.someimage);
Bitmap bitmap = BitmapFactory.decodeStream(is);
try
{
int[] pixels = new int[32*32];
bitmap.getPixels(pixels, 0, 800, 0, 0, 32, 32);
}
catch(ArrayIndexOutOfBoundsException ex)
{
Log.e("testing", "ArrayIndexOutOfBoundsException", ex);
}
Why on earth do I keep getting an ArrayIndexOutOfBoundsException? the pixels array is 32x32 and as far as I'm aware I'm correctly using getPixels. The image dimensions is 800x800 and I am attempting to retrieve a 32x32 section. The image is a 32-bit PNG which is being reported as ARGB-8888.
Any ideas? even if I'm being an idiot! I'm about to throw the keyboard out of the window :D
use bitmap width as stride, in ur case 32
bitmap.getPixels(pixels, 0, 32, 0, 0, 32, 32);
every row gap with 800 causes ur pixelarray to get out of bound
"I'm about to throw the keyboard out of the window " funny lol
You're overflowing the destination buffer because you're asking for a stride of 800 entries between rows.
http://developer.android.com/reference/android/graphics/Bitmap.html#getPixels%28int[],%20int,%20int,%20int,%20int,%20int,%20int%29
You getting OutOfBounds exception becacuse stride is applied to pixels array not to the original bitmap,so in your case you're trying to retrieve 32*800 pixels which doesn't fit into your array.

placeing bitmaps in live wallpapers

Hello I am trying to place acouple bitmaps on the screen and rotate them. I can get this to work by doing
canvas.drawBitmap(pic2, rotatePic, null);
rotatePic is matrix with
postRotate(5, pic2.getHieght()/2, pic2.getWidth()/2)
this rotates the pic and puts it at 0, 0 so to place it i tried
Bitmap topPic = Bitmap.createBitmap(pic2, 0, 0, pic2.getWidth(),
pic2.getHeight(), rotatePic, false);
than place with
canvas.drawBitmap(topPic, 200, 100, null);
it places it correctley but it no longer rotates correctley it looks like it is bouncing and spinning I've tried everthing
You can alternatively try rotating the canvas itself, using
canvas.rotate(degress, px, py);
Here's a link to the Android reference page for this:
Canvas.rotate();
Hope this helps!!

Categories

Resources