I don't have any problem managing textures. But I didn't work that much with loading textures from images. All I know is that the texture needs to be of size 2^i by 2^i.
But what's the best technique to load any images into a texture. If the images is not a square, I can fit it in the square and add two black parts to fill what is missing. But I'm not sure how to do the stretching.
So, if I have an image of let say 800x600 and I want to put it in a 512x512 square, what's the best trick to copy the pixels into texture ? Or, specially on Android, is there some functions that exists that would do that for me ? In short, it's like I want to resize the 800x600 image to be 512x384 and put it in the texture. But I want to preserve as much information as I can.
The OP Answered his own question with:
SOLVED: a friend showed me some references that covers what I want.
To resize, you can do it with the Bitmap class of Android. You can specify a Matrix, just like the one used for OpenGL to resize the Bitmap. From that point, I expect the pixels to be well preserved and will be able to put them in the texture.
If they come back and put the answer here themselves and accept it then I will delete this answer.
Related
I'm currently able to blur a whole bitmap (by resizing it down than up for example).
The effect I'm trying to accomplish is a selective blur : the result bitmap would be blurred, minus a round / oval part of it which would still be sharp :
The difficult part is that the sharp oval part could be smaller or bigger, and should be movable (its coordinates aren't always the center of the original bitmap).
I already found a solution, but I don't think of it as a good performance wise solution :
Copy the original bitmap into two different bitmaps (background and foreground)
Blur the background one
Crop the foreground one into the desired shape (round or oval)
Erase the borders of the foreground a bit (to avoid a too sharp difference between foreground and background images)
Put back the two images together
Export it as a bitmap
One another solution could be to recreate a blur algorithm which would run through every pixel of the original bitmap and apply an amount of blur higher or lower depending on the portion of the bitmap.
I finally decided to follow my first idea, using #DerGolem links. Here is the updated version of the chart :
The algorithm is quite simple:
We create two copies of the bitmap : the first one will serve as the background, while the other one will be used as the sharp part of the picture. To avoid the second one to be too sharp, we'll use a prepared mask (stored in the drawables folder)
We blur the first one as much as we want
We apply the mask to the second bitmap
We create a bitmap from those two previous steps
I created a sample demo application, hosted on BitBucket. You can clone the project and try it, the performances are much better than what I expected!
In order to achieve this, I used the following resources:
RenderScript to blur the background, much better than resizing the image down and up : 1, 2
Understand Porter/Duff
As said in the project's readme, the provided code is far from being perfect, but it works.
I'm having trouble cleanly down-scaling images on Android. I'm looking to scale small PNG images between arbitrary sizes of about 10-100% of their original size.
I've created a sample image to demonstrate the problem and exacerbate the unusual behaviors I'm seeing in Android's image scaler:
The above image is a screenshot from an Android device with some annotations added. I've also added the same images in a second column on the left side showing how they are rendered with a linear scaling by "The GIMP" (GNU Image Manipulation Program).
The base image consists of a checkerboard pattern background of red and blue pixels. On that background I've drawn some 1px-wide yellow lines and fairly thin green text. The image is 288x288 pixels.
When scaling the image to 1/3 of its original dimensions, Android seems to simply grab one in nine pixels, throwing out all other data. Some of the yellow lines disappear entirely as a result. Remarkably, the checkerboard pattern remains intact (which is simply a result of every 3rd pixel being used).
When scaling the image to a dimension of near-but-not-exactly 50% of its original size, e.g., 142x142 or 143x143, the scaler creates some fairly large anomalies/artifacts on the image.
At 50% size (144x144), the image looks correct.
The test image does bring out the worst of the image scaler, but "normal" PNG icon images are severely impacted as well. From 10-33% or so the images aren't properly resampled, and thus appear extremely "bitmapped". And certain larger size images have very strange anomalies in them at certain sizes.
If anyone knows a means to disable this strange scaling behavior, even at a performance cost, I'd greatly appreciate knowing about it. It can certainly be solved by writing an algorithm that works directly on the pixels of bitmaps, but I'm hopeful that isn't the only option.
Also noteworthy is the fact that all image work is being done with ARGB_8888 Bitmap.Configs. I've tried manipulating image size by setting maxwidth/maxheight on ImageViews, by using Bitmap.createScaledBitmap(), and by using Bitmap.createBitmap with a Matrix. All attempts have this same result. Bitmap filtering is enabled.
Thanks again for any suggestions!
Using Bitmap.createScaledBitmap() and Bitmap.createBitmap with a Matrix is the same; see the source for Bitmap.createScaledBitmap (which hasn't changed since Android 2).
On Android 4.0+, using a matrix (as in Bitmap.createScaledBitmap) allows hardware-accelerated operations if enabled (enabled by default on 4.1+ IIRC), thus we doesn't have direct control over what is being done and how it is done.
That means you'll have to implement your own scaling method using the desired (here, linear) filtering; either by pixel processing; or using OpenGL ES with the good filter, but it may not be available on all devices.
i would like to know whether is it possible to merge several images to form one complete image. For my case, is a floor plan that is split in 18 small images and i would like to merge them into one. I had one idea but not sure whether is it workable. My idea is this:
I would first place the top left most image first, with the x and y coordinates as (0,0).
Next for the subsequent images (right/bottom of this first image), using the width and height of the image, i would find out the coordinates where the next image would be placed. Doing this i presume would required 18 ImageView to achieve that.
Btw, these 18 images are .gif format and so do i need to like convert them to Bitmap or something before i can display them using ImageView?
You could merge the images to a bigger images by drawing the small images to a canvas associated with the resulting big bitmap
Canvas c=new Canvas(result_bitmapenter);
and then draw your small images onto the canvas
c.drawBitmap(small,...);
But that might not be the best way as big images eat lots of memory - perhaps you should concider dynamic loading instead of merging then
Yes its possible create a Bitmap object large enough to hold the whole floor plan and use Canvas to paint them into to the large bitmap. Be sure to cache it or you'll be recreating it every time and you'll have to convert it to png for compatibility with older devices.
I've currently been trying to optimize my app with RGB_565 textures rather than RGBA_8888 textures. All is well except when I try to re-size these textures? Is there some hard coded reason why I can't simply make these textures smaller?
I'm trying to keep all my textures larger than necessary so I can scale down; thus being able to dynamically scale the textures for larger screens to have better image quality. This doesn't seem to work with RGB_565 or I'm missing something :-?.
Should I just create a few different copies and dynamically LOAD the correct one rather than SCALE it? Thanks for any help you can offer!
[EDIT]
The whole point here is that I can't dynamically re-size/scale these textures once loaded into the app? They stretch like pulled from top right and bottom left of screen when I try to reduce their size even...?
Has to do with the GL blend functions that can be used. Didn't get into it, simply re-sized them statically for now, but when I do get into it again I'll be sure to post the code!
consideration notes: extending SurfaceView, implementing SurfaceHolder.Callback, and loading in bitmap(.png) images to render the canvas (9x9 grid).
I am trying to get the system to resize the images for me so that I don't have to manually create up-to 4 copies of everything (even 3*77 bitmaps is bad overhead [and yes I need all 77 potentially]) I would prefer just having 77 image files in res/drawables(not all of them will be drawn at any given time; at most maybe 38, but needs to be dynamicly capable to change them out).
Q1: how do I get the system to resize the images without doing the white space thing that android.develop talks about for .9.png (considering that all of my grid images have black borders, and need to butt-up together)?
Q2: is there a unifying screen proportionality (4:3, 5:4) that I can fall back on so that diagonal lines don't look really bad?
A1:
Bitmap b= BitmapFactory.decodeResource(context.getResources(), R.drawable.b);
b=Bitmap.createScaledBitmap(b,newWidth, newHeight, true);
A2: i don't think so