I am producing a Bitmap from a RelativeLayout that contains another Bitmap from a MapView set as the background plus two other views (icon & text) in the right hand corner. I'm getting the image I want but it is low quality. I've search high and low and found many pages on converting Views to Bitmaps but nothing regarding quality. I'm guessing it might be something to do with scaling.
The output image:
The code:
public Bitmap getBitmapFromMapView() {
// Get Bitmap from MapView
Bitmap mapBitmap = Bitmap.createBitmap(mMapView.getWidth(), mMapView.getHeight(), Bitmap.Config.ARGB_8888);
Canvas mapCanvas = new Canvas(mapBitmap);
mMapView.draw(mapCanvas);
// Inflate RelativeLayout view containing ImageView (FlagIt icon) and TextView (URL) in bottom-right corner
// and merge it with the MapView Bitmap to produce an Overall Bitmap containing everything
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
RelativeLayout overallRelativeLayout = (RelativeLayout) inflater.inflate(R.layout.screenshot, null);
overallRelativeLayout.setBackgroundDrawable(new BitmapDrawable(mapBitmap));
overallRelativeLayout.measure(
MeasureSpec.makeMeasureSpec(mMapView.getWidth(), MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(mMapView.getHeight(), MeasureSpec.EXACTLY));
overallRelativeLayout.layout(0, 0, overallRelativeLayout.getMeasuredWidth(), overallRelativeLayout.getMeasuredHeight());
Bitmap overallBitmap = Bitmap.createBitmap(mMapView.getWidth(), mMapView.getHeight(), Bitmap.Config.ARGB_8888);
Canvas overallCanvas = new Canvas(overallBitmap);
overallRelativeLayout.draw(overallCanvas);
return overallBitmap;
}
and the inflated screenshot.xml XML file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/screenshot_corner_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="4dip"
android:layout_marginRight="4dip"
android:shadowColor="#000000"
android:shadowDx="0.0"
android:shadowDy="0.0"
android:shadowRadius="4"
android:text="http://www.aroha.ws"
android:textColor="#ff0000"
android:textSize="18sp"
android:textStyle="bold" />
<ImageView
android:id="#+id/screenshot_corner_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#id/screenshot_corner_text"
android:layout_alignParentRight="true"
android:layout_marginBottom="4dip"
android:layout_marginRight="4dip"
android:src="#drawable/corner_title_icon" />
</RelativeLayout>
The RelativeLayout when displayed on my screen looks better quality:
output image desired quality http://5312208804164438257-a-1802744773732722657-s-sites.googlegroups.com/site/arohacorp/pilcrowpipeblog/device-2012-04-20-224931.png
Related
I know there are lots of question about this topic. But still I need help. I want to show my ImageView has equal width and height in my TableLayout. But on different devices I couldn't be able to do this.
Here is I get the image using URL in AsyncTask, and set the ImageView on onPostExecute method.
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
// set the imageview
bmImage.setImageBitmap(result);
}
Here is my XML file (news.xml) where my ImageView located
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="10dp"
android:paddingEnd="10dp"
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp"
android:paddingBottom="10dp"
android:id="#+id/mylayout"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/image"
android:clickable="true"
android:background="#drawable/border"/>
<TextView
android:layout_width="match_parent"
android:layout_height="75dp"
android:maxLines="4"
android:id="#+id/text"
android:layout_below="#+id/image"
android:layout_alignEnd="#+id/image"
android:layout_alignRight="#+id/image"
android:clickable="true"
android:textSize="18sp"
android:background="#e3e3e3"
android:paddingTop="10dp"
android:gravity="center_vertical"
/>
</RelativeLayout>
I thought that I can create a TableLayout, and locate the View (above) inside a TableRow like, side by side 2 view.(view is above)
To do this I get the screen width and subtract the paddings and divide by 2 and give that width to the ImageView to be able to get same size for all image views.
Here is my code,
DisplayMetrics metrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
screenWidth = metrics.widthPixels;
tableLayout = (TableLayout) view.findViewById(R.id.tableLayout);
Log.e("screenwidth",":"+screenWidth);
// here is my paddings converted to pixel and will be subtracted from screen width
int pixValue = (int) (20 * Resources.getSystem().getDisplayMetrics().density);
int imageWidthPix = ( screenWidth - pixValue ) / 2;
Log.e("imageWidthPix ",":"+imageWidthPix );
for (int i = 0; i < categoryNews.get(myString).size(); i++) {
if (i % 2 == 0) {
tr = new TableRow(getActivity());
tableLayout.addView(tr);
}
//here is where my ImageView layout (news.xml)
View oneNews = inflater.inflate(R.layout.news, null);
ImageView imageView = (ImageView) oneNews.findViewById(R.id.image);
TextView textView = (TextView) oneNews.findViewById(R.id.text);
//here I set the width as I want
imageView.setLayoutParams(new RelativeLayout.LayoutParams(imageWidthPix, RelativeLayout.LayoutParams.WRAP_CONTENT));
String imagePath = "http://my.url.com/" + categoryNews.get(myString).get(i).getImagePath();
new DownloadImageTask(imageView,getActivity().getApplicationContext())
.execute(imagePath);
I got the perfect result on my phone. But on the different device which has different screen size, ImageView has spaces on top and bottom. I tried to convert nine patch chunk and convert that into again bitmap but there were no difference. If I wouldn't get the images from web service, I would put other resolution images into mipmap-hpdi, mipmap-mdpi etc folders and there would be no error. But I am getting images dynamically so how can achieve that ImageView has half of screen width?
Thanks in advance.
Here I have edited your xml
Try Linear layout with weights,change the weight according to your need, change the layout_weight to make your image view and textview smaller or larger.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="10dp"
android:orientation="vertical"
android:id="#+id/mylayout"
android:weightSum="10">
<ImageView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="3"
android:id="#+id/image"
android:src="#drawable/sd"
android:clickable="true"/>
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:maxLines="4"
android:id="#+id/text"
android:clickable="true"
android:textSize="18sp"
android:background="#e3e3e3"
android:paddingTop="10dp"
android:gravity="center_vertical"
/>
</LinearLayout>
Simple layout
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0099cc"
tools:context="com.testzoom.app.FullscreenActivity">
<TextView android:id="#+id/fullscreen_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true"
android:textColor="#33b5e5"
android:textStyle="bold"
android:textSize="50sp"
android:gravity="center"
android:text="#string/dummy_content" />
<Button android:id="#+id/dummy_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/dummy_button"
android:layout_gravity="bottom"
/>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:id="#+id/dummy_image"
/>
</FrameLayout>
Goal - by pressing button on the bottom, set imageview(which is same size as screen) with screenshot bitmap of half size. Result - weird rendering, why fitXY not working?
Click handler:
findViewById(R.id.dummy_button).setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
View view = getWindow().getDecorView();
Bitmap bmp = Bitmap.createBitmap(view.getWidth()/2, view.getHeight()/2, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bmp);
c.scale(0.5f,0.5f, bmp.getWidth(), bmp.getHeight());
view.draw(c);
((ImageView)findViewById(R.id.dummy_image)).setImageBitmap(bmp);
}
});
Result on screenshots:
Note that this task is synthetic so don't ask why I am doing this, this is just demonstration of problem.
The problem lies within the call where you are scaling the canvas. You provide the pivot points which are bmp.getWidth() and bmp.getHeight() which are essentially in the middle of the screen.
findViewById(R.id.dummy_button).setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
View view = getWindow().getDecorView();
Bitmap bmp = Bitmap.createBitmap(view.getWidth()/2, view.getHeight()/2, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bmp);
c.scale(0.5f,0.5f);//no pivot points
view.draw(c);
((ImageView)findViewById(R.id.dummy_image)).setImageBitmap(bmp);
}
});
I don't think it's the rendering so much as the placement of the new ImageView. You have all three items in a FrameLayout which does nothing to determine the order or placement of view. Where is the code to place the newly created ImageView?
I have the following TextView layout:
<TextView
android:layout_width="10dp"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:drawableTop="#drawable/ic_launcher" >
I inflate this layout in code, and want to use Android-Universal-Image-Loader to load the image into drawableTop. But, as I understand, there's no way to get backgroundTop's ImageView from TextView, thus I can't use AUIL. Is there any way to get ImageView for background, and if not, how should I modify the layout so that it will have ImageView but will look the same as the original layout?
You can use listener (ImageLoadingListener) for that. Put following code in onLoadingComplete(...)
void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
Drawable topImage = new BitmapDrawable(loadedImage);
textView.setCompoundDrawablesWithIntrinsicBounds(null, topImage, null null);
}
Use a RelativeLayout with ImageView and TextView then manipulate ImageView
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_alignBottom="#+id/textView1"
android:layout_alignLeft="#+id/textView1"
android:layout_alignRight="#+id/textView1"
android:layout_alignTop="#+id/textView1"
android:src="#drawable/ic_launcher" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</RelativeLayout>
TextView tv = (TextView) findViewById(R.id.TV);
Drawable top = getResources().getDrawable(R.drawable.icon) ;
tv.setCompoundDrawablesWithIntrinsicBounds(null, top, null, null) ;
// tv.setCompoundDrawablesWithIntrinsicBounds(left, top, right, bottom)
How to display text on android ImageView with Linear Layout. I found many examples on stack overflow for this purpose but all are for Relative Layout, Frame Layout But I am not getting it in Linear Layout.
I have tried for android:text="My Text" But its not working.
Please suggest me if its possible to do so. If so how can it be done.
<ImageView
android:id="#+id/share_button"
android:layout_width="fill_parent"
android:layout_height="25dp"
android:layout_gravity="center"
android:layout_margin="5dp"
android:layout_weight="2"
android:text="text"
android:background="#drawable/iosbutton" />
This is the Image attached to this ImageView on which I want to display text in the center.
Try this
Use this method
public BitmapDrawable writeOnDrawable(int drawableId, String text){
Bitmap bm = BitmapFactory.decodeResource(getResources(), drawableId).copy(Bitmap.Config.ARGB_8888, true);
Paint paint = new Paint();
paint.setStyle(Style.FILL);
paint.setColor(Color.BLACK);
paint.setTextSize(20);
Canvas canvas = new Canvas(bm);
canvas.drawText(text, 0, bm.getHeight()/2, paint);
return new BitmapDrawable(bm);
}
call like this
ImageView image=(ImageView)findViewById(R.id.imageView1);
image.setImageDrawable(writeOnDrawable(R.drawable.ic_launcher,"Hello"));
Does it have to be an ImageView?
<TextView
android:id="#+id/share_button"
android:layout_width="fill_parent"
android:layout_height="25dp"
android:layout_gravity="center"
android:layout_margin="5dp"
android:layout_weight="2"
android:text="text"
android:gravity="center"
android:background="#drawable/iosbutton" />
Im trying to implement a GridView as part of a image gallery. I followed the following example from the Android developer portal.
The tutorial seems to work for all screen sizes. As you can see below the proportions for a small and a large screen size are displayed correctly (on the left - small screen size, on the right - large screen size.
But now to my problem. When I want to implement exactly the same GridView within a LinearLayout from my Android Project - the correct proportions are gone - as shown by the images below. The pictures begin to overlap so forth and so on.
I am quite sure that this has something to with my LinearLayout which looks like the following.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/widget64"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/widget34"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:background="#drawable/foto_detail_bg_cell_0"
>
<ImageView
android:id="#+id/flyer"
android:layout_width="100dp"
android:layout_height="80dp"
android:src="#drawable/icon"
android:scaleType="centerCrop"
/>
<LinearLayout
android:id="#+id/widget36"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5px"
android:orientation="vertical">
<TextView
android:id="#+id/toptext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Beat.It"
android:textSize="16sp"
android:textStyle="bold"
android:textColor="#color/white"/>
<TextView
android:id="#+id/widget39"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="http://www.google.at"
android:textColor="#color/white"/>
<LinearLayout
android:id="#+id/widget40"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/widget41"
android:layout_width="58dp"
android:layout_height="40dp"
android:src="#drawable/facebook_share"/>
<ImageView
android:id="#+id/widget42"
android:layout_width="58dp"
android:layout_height="40dp"
android:layout_marginLeft="1dp"
android:src="#drawable/photocount"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gridview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:columnWidth="90dp"
android:numColumns="auto_fit"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:gravity="center"
/>
</LinearLayout>
The MAIN QUESTION:
The Layout XML used by the tutorial on the Android developer portal only uses the GridView alone, without a LinearLayout and and it is shown with correct proportions on each screen size. Why is that? And why does it not work properly when I nest the GridView in a Linear Layout like in my project?
SOLVED:
I solved this issue by editing the ImageAdapter of the GridView. I calculated the size of the generated image views - density independent.
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
//Calculation of ImageView Size - density independent.
//maybe you should do this calculation not exactly in this method but put is somewhere else.
Resources r = Resources.getSystem();
float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 60, r.getDisplayMetrics());
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams((int)px, (int)px));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
//imageView.setPadding(8, 8, 8, 8);
imageView.setBackgroundColor(Color.BLUE);
} else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
To adjusting Gridview to screen size
In onCreate take rowHeight :
//Get root view
root = binding.root
// Or you can use findviewbyid(R.id.root)
view.onGlobalLayout {
rowHeight =
root.measuredHeight / currentPageNumberOfRow
fillView(appsList)
}
In adapter:
override fun getView(position: Int, ConvertView: View?, parent: ViewGroup?): View? {
var mConvertView = ConvertView
if (layoutInflater == null) {
layoutInflater =
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as
layoutInflater!!.inflate(R.layout.item_app_shortcut, null)
}
if (mConvertView == null) {
mConvertView =
layoutInflater!!.inflate(R.layout.item_child_launcher_app, null)
//Add this:
mConvertView.layoutParams = AbsListView.LayoutParams(GridView.AUTO_FIT, rowHeight)
}
Dont forget set row image:
android:layout_width="0dp"
android:layout_height="0dp"
To fit on screen