I am making a icon for my app.. The app is basically a friend finder. I am creating a overlay that looks much like the icons from Google Latitude. I have an image that changes due to the user and I have the boarder. I've been able to do the layered drawable and overlay fine, but the problem is, the image stretches to the size of the border. This is a problem because, if you've never seen the Google Lat icons, it has a point on the bottom with open space between it.
What I need to do is, somehow restrict the size of the changing image to the bounds of the square portion of the border. Any Help would be much appreciated. Here is my snippet:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 25;
Bitmap bit = BitmapFactory.decodeFile(photo, options);
draw = new BitmapDrawable(bit);
Resources r = getResources();
Drawable[] layers = new Drawable[2];
layers[0] = draw;
layers[1] = r.getDrawable(R.drawable.border);
LayerDrawable layerDrawable = new LayerDrawable(layers);
draw = layerDrawable;
}else{
draw = this.getResources().getDrawable(R.drawable.androidmarker);
}
HelloItemizedOverlay itemizedoverlay = new HelloItemizedOverlay(draw, this);
GeoPoint point = new GeoPoint(lat,lon);
OverlayItem overlayitem = new OverlayItem(point, username, avail + " : " + status + " : Position updated at : " + update_at);
items.add(overlayitem);
itemizedoverlay.addOverlay(overlayitem);
mapOverlays.add(itemizedoverlay);
Funny that shorty after I posted this, I found the answer. I was looking in all of the wrong places to resize the image. I tried the bitmap, the drawable, the layers inside of the layerdrawable. But, what I never tried was the layerdrawable itself. The solution is below:
Resources r = getResources();
Drawable[] layers = new Drawable[2];
layers[0] = draw;
layers[1] = r.getDrawable(R.drawable.border);
LayerDrawable layerDrawable = new LayerDrawable(layers);
layerDrawable.setLayerInset(0, 0, 0, 0, 12);
draw = layerDrawable;
The layerDrawable inset method is as follows:
layerDrawable.setLayerInset(*index of layer*, *left inset*, *top*, *right*, *bottom*);
Thanks guys!
Related
How do I use the Rect rect = face.getBoundingBox() data to crop out the detected face from the bitmap and save it as a new bitmap. Ive attempted to construct the bitmap using rect.left etc and simply display the extracted face in imageview.. but it does not seem to work.
Also, is it possible to access the faces directly?
If I understand correctly the detector creates a List of FirebaseVisionFace, what are these listings?
How does it list a face?
Is it possible to access them?
private void processFaceDetection(final Bitmap bitmap) {
FirebaseVisionImage firebaseVisionImage = FirebaseVisionImage.fromBitmap(bitmap); //firebaseVisionImage is an object created from bitmap firebase uses to detect faces
FirebaseVisionFaceDetectorOptions firebaseVisionFaceDetectorOptions = new FirebaseVisionFaceDetectorOptions.Builder().build();
FirebaseVisionFaceDetector firebaseVisionFaceDetector = FirebaseVision.getInstance().getVisionFaceDetector(firebaseVisionFaceDetectorOptions);
firebaseVisionFaceDetector.detectInImage(firebaseVisionImage).addOnSuccessListener(new OnSuccessListener<List<FirebaseVisionFace>>() {
#Override
public void onSuccess(List<FirebaseVisionFace> firebaseVisionFaces) {
int counter = 0;
for (FirebaseVisionFace face : firebaseVisionFaces) {
Rect rect = face.getBoundingBox();
RectOverlay rectOverlay = new RectOverlay(graphicOverlay, rect);
graphicOverlay.add(rectOverlay);
Bitmap faceSaved = Bitmap.createBitmap(Math.round(Math.abs(rect.left - rect.right)), Math.round(Math.abs(rect.top - rect.bottom)), Bitmap.Config.ALPHA_8);
imageview.setImageBitmap(facesaved);
imageview.setVisibility(View.VISIBLE);
counter++;
}
ANSWER:
To use the rect data, which can be gathered using rect.toShortString(), produces 4 values for left, top, right, bottom. i.e. [280,495][796,1011]. These are created by the FirebaseVisionFaceDetector and are stored in a list (List) for each detected face.
To save the bitmap data contained within different rects(faces)
for (FirebaseVisionFace face : firebaseVisionFaces) {
Rect rect = face.getBoundingBox();
Bitmap original = Bitmap.createScaledBitmap(capturedImage, cameraView.getWidth(), cameraView.getHeight(), false); //scaled bitmap created from captured image
Bitmap faceCrop = Bitmap.createBitmap(original, rect.left, rect.top, rect.width(), rect.height()); //face cropped using rect values
faceCrop contains the face-only bitmap data contained within the parameters of the rect.
Hope this helps....
This is my code:
Image image1 = new Image(url);
Dialog mainDialog = new Dialog(true);
ImageView imageView = new ImageView();
imageView.setImage(image1);
imageView.setPreserveRatio(true);
imageView.setCache(true);
imageView.setSmooth(true);
imageView.setPickOnBounds(true);
imageView.setOnZoom(evt->{
imageView.setScaleX(imageView.getScaleX()*evt.getZoomFactor());
imageView.setScaleY(imageView.getScaleY()*evt.getZoomFactor());
});
mainDialog.setContent(imageView);
Platform.runLater(() -> mainDialog.showAndWait());
You don't provide much information about the image quality, and what do you mean by pixelated, at what scale it happens, or if it is only on mobile and not on desktop.
Anyway, here are a few hints to improve the results.
Add a hint to the cache, in this case CacheHint.SCALE.
Add clipping to the imageView. If the scale is too big, the image will be big on memory. This will prevent a possible memory issue. Bind the size of the rectangle to the view dimensions.
This works fine for me, even with scale factors of 20+:
Image image1 = new Image(url);
Dialog mainDialog = new Dialog(true);
ImageView imageView = new ImageView();
imageView.setImage(image1);
imageView.setPreserveRatio(true);
imageView.setCache(true);
imageView.setCacheHint(CacheHint.SCALE); // <-- hint
imageView.setSmooth(true);
imageView.setPickOnBounds(true);
imageView.setOnZoom(evt -> {
imageView.setScaleX(imageView.getScaleX() * evt.getZoomFactor());
imageView.setScaleY(imageView.getScaleY() * evt.getZoomFactor());
});
Rectangle r = new Rectangle();
imageView.setClip(r); // <-- clip
r.widthProperty().bind(view.widthProperty());
r.heightProperty().bind(view.heightProperty());
mainDialog.setContent(imageView);
mainDialog.showAndWait(); // <-- No need of runLater
I'm currently making an app that displays the photos on the map using an icon. However it displays very big photos. How can you actually resize an icon in google maps?
Here is my code for adding a marker:
mMap.addMarker(new MarkerOptions().position(new LatLng(Latitude, Longitude)).title("Picture")
.snippet("picture" + i)
.flat(true)
.icon(BitmapDescriptorFactory.fromPath(listFile[i].getAbsolutePath()))
);
Need to perform just two steps:
Know the height and width of the bitmap before loading this using this code:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
Change it to the size you want and pass it as icon in Your maps as markers:
Bitmap b = BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length)
profileImage.setImageBitmap(Bitmap.createScaledBitmap(b, 150, 80, false));
Resize the Bitmap before adding it as a Marker.
If this question is repeated then let me know the link of original question because i enable to findout the good link for resolve my current problem.
I am working on android camera I able to take Picture's from my app. But I want to write name on the top of taken picture. i enable to find out how can i resolve this issue.
Sorry for i don't have any code for take reference.....
any help will be appreciated and i want to pay my thank in advance to all of you.
Try following code.
public Bitmap drawTextToBitmap(Bitmap bitmap, String mText) {
try {
android.graphics.Bitmap.Config bitmapConfig = bitmap.getConfig();
// set default bitmap config if none
if(bitmapConfig == null) {
bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
}
// resource bitmaps are imutable,
// so we need to convert it to mutable one
bitmap = bitmap.copy(bitmapConfig, true);
Canvas canvas = new Canvas(bitmap);
// new antialised Paint
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
// text color - #3D3D3D
paint.setColor(Color.rgb(110,110, 110));
// text size in pixels
paint.setTextSize((int) (12 * scale));
// text shadow
paint.setShadowLayer(1f, 0f, 1f, Color.DKGRAY);
// draw text to the Canvas center
Rect bounds = new Rect();
paint.getTextBounds(mText, 0, mText.length(), bounds);
int x = (bitmap.getWidth() - bounds.width())/6;
int y = (bitmap.getHeight() + bounds.height())/5;
canvas.drawText(mText, x * scale, y * scale, paint);
return bitmap;
} catch (Exception e) {
return null;
}
}
I'm working with GeoTiff/PNG files too large for handling as a whole in my code.
Is there any possibility to decode specific areas (e.g. given by two x,y coordinates) of a file in bitmapfactory? Haven't found anything looking similar at http://developer.android.com/reference/android/graphics/BitmapFactory.html(Android's developer reference).
Thanks!
With kcoppock's hint I've set up the following solution.
Though I'm wondering why rect needs to be initialized by Rect(left, bottom, right, top) instead of Rect(left, top, right, bottom)...
Example call:
Bitmap myBitmap = loadBitmapRegion(context, R.drawable.heightmap,
0.08f, 0.32f, 0.13f, 0.27f);
Function:
public static Bitmap loadBitmapRegion(
Context context, int resourceID,
float regionLeft, float regionTop,
float regionRight, float regionBottom) {
// Get input stream for resource
InputStream is = context.getResources().openRawResource(resourceID);
// Set options
BitmapFactory.Options opt = new BitmapFactory.Options();
//opt.inPreferredConfig = Bitmap.Config.ARGB_8888; //standard
// Create decoder
BitmapRegionDecoder decoder = null;
try {
decoder = BitmapRegionDecoder.newInstance(is, false);
} catch (IOException e) {
e.printStackTrace();
}
// Get resource dimensions
int h = decoder.getHeight();
int w = decoder.getWidth();
// Set region to decode
Rect region = new Rect(
Math.round(regionLeft*w), Math.round(regionBottom*h),
Math.round(regionRight*w), Math.round(regionTop*h));
// Return bitmap
return decoder.decodeRegion(region, opt);
}
You should look into BitmapRegionDecoder. It seems to describe exactly the use case that you are looking for.
I don't know exactly what you mean by "Decode specific areas" but if by decoding you mean, to actually "copy" certain areas of a bitmap, what you can do is make use of canvas in order to get it as shown below:
Bitmap bmpWithArea = Bitmap.createBitmap(widthDesired, heightDesired, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmpWithArea);
Rect area = new Rect(arealeft, areatop, arearight, areabottom);
Rect actualSize = new Rect(0, 0, widthDesired, heightDesired);
canvas.drawBitmap(bitmapWithAreaYouWantToGet, area, actual, paintIfAny);
//And done, starting from this line "bmpWithArea" has the bmp that you wanted, you can assign it to ImageView and use it as regular bmp...
Hope this helps...
Regards!