I have the problem that I have a layout with an ImageView. With AsyncTask I load an image from the web. It is a panorama picture. If I start up the Fragment, the image I load with src="#drawable/pano" is shown perfectly. It has full height and I can scroll through the panorama.
As soon as the new image is loaded into the ImageView the imageview rescales so that the height is:
Before the AsyncTask (Image is loaded from drawables...):
And this is after the AsyncTask loaded the image:
Here is my xml file:
<RelativeLayout 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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:overScrollMode="never"
android:scrollbars="none" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/img1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:src="#drawable/pano" />
</RelativeLayout>
</HorizontalScrollView>
AsyncTask Code:
public class DownloadPanorama extends
AsyncTask<ImageView, Void, Bitmap> {
ImageView imageView;
Bitmap bm;
public DownloadPanorama(ImageView mChart) {
imageView = mChart;
}
#Override
protected Bitmap doInBackground(ImageView... imageViews) {
return download_Image((String) imageView.getTag());
}
#Override
protected void onPostExecute(Bitmap result) {
imageView.setImageBitmap(result);
}
private Bitmap download_Image(String url) {
Bitmap bm = null;
try {
URL aURL = new URL(url);
URLConnection conn = aURL.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
bm = BitmapFactory.decodeStream(bis);
bis.close();
is.close();
return bm;
}
}
Also happens when not using AsyncTask and only using raw setImageBitmap... So I don't know if I have to change the scaleType in my xml file or if I need to set it again after loading a new image?
I would try changing:
android:layout_height="wrap_content"
to
android:layout_height="fill_parent"
in your ImageView.
If that doesn't work, you might be able to scale your bitmap:
myBitmap = Bitmap.createScaledBitmap(myBitmap, width, height,true);
EDIT
It sounds like from your comments and updated question that you know the size you would like the image to be (1200x400). You have two things you can do to get this size. The first, and recommended, is to replace the line
bm = BitmapFactory.decodeStream(bis);
with
BitmapFactory.Options options = new BitmapFactory.Options();
options.outWidth=1200;
options.outHeight=400;
bm = BitmapFactory.decodeStream(bis, new Rect(0,0,0,0), options);
The other option is to change your View bounds. In your comments above, it sounds like the bounds might change, so you would have to repeat this each time you loaded a new image of different size:
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) imageView.getLayoutParams();
params.width = 1200;
params.height = 400;
imageView.setLayoutParams(params);
You need to change
android:adjustViewBounds="true"
to
android:adjustViewBounds="false"
Related
I am using the below code for taking screenshot in my application.
View rootView = findViewById(android.R.id.content).getRootView();
rootView.setDrawingCacheEnabled(true);
rootView.buildDrawingCache(true);
Bitmap bitmap = rootView.getDrawingCache();
But I am getting an image with two black portion in the top and bottom by the notification and navigation bars. I need to remove those black areas. I need not to replace those area with the notification and navigation bars. But i need the toolbar.
take the drawing cache of the root Layout as below:
//onCreate
setContentView(R.layout.activity_main);
layout = (RelativeLayout) findViewById(R.id.activity_main);
layout.setDrawingCacheEnabled(true);
And to get bitmap, the usual way,
Bitmap bitmap = layout.getDrawingCache();
activity_main:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.Toolbar
android:id="#+id/toolBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="#color/colorPrimary" />
<!--other content-->
</RelativeLayout>
Use Below Method:
public static Bitmap loadBitmapFromView(Context context, View v) {
DisplayMetrics dm = context.getResources().getDisplayMetrics();
v.measure(View.MeasureSpec.makeMeasureSpec(dm.widthPixels, View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(dm.heightPixels, View.MeasureSpec.EXACTLY));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
Bitmap returnedBitmap = Bitmap.createBitmap(v.getMeasuredWidth(),
v.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(returnedBitmap);
v.draw(c);
return returnedBitmap;
}
Pass your parent view inside the argument.
Take this to another Linear Layout
<LinearLayout
android:id="#+id/linear"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/munch"
android:id="#+id/munchscreen"/>
<ImageView
android:layout_width="200dp"
android:layout_height="200dp"
android:id="#+id/screenshots"
android:contentDescription="#string/app_name"
/>
</LinearLayout>
Now find Id for this Linear Layout on oncreate() method making it global variable
LinearLayout ll;
ll = (LinearLayout)findViewById(R.id.linear);
now capture this screen:
ll.setDrawingCacheEnabled(true);
ll.buildDrawingCache(true);
Bitmap cs = Bitmap.createBitmap(ll.getDrawingCache());
ll.setDrawingCacheEnabled(false);
Now set this bitmap to your ImageView.
Following is the XML layout file where I have added a button, textview and an imageview in a linear layout. And I have also added onClick attribute in the button.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_screenshoat"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.ncrypted.myapplication.Screenshoat">
<Button
android:id="#+id/btnScreenshot"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Taake screen shot"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/imageView"/>
</LinearLayout>
This is android activity file where I have added some java code to take screenshot and import android.graphics.Bitmap;, java.io.ByteArrayOutputStream;, java.io.File; etc.
public class Screenshoat extends AppCompatActivity {
Button btnScreenshot;
Bitmap mbitmap;
ImageView imageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_screenshoat);
btnScreenshot = (Button) findViewById(R.id.btnScreenshot);
imageView = (ImageView) findViewById(R.id.imageView);
btnScreenshot.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mbitmap = getBitmapOFRootView(v);
imageView.setImageBitmap(mbitmap);
createImage(mbitmap);
Toast.makeText(Screenshoat.this, "Screen shoat created", Toast.LENGTH_SHORT).show();
}
});
}
public Bitmap getBitmapOFRootView(View v) {
View rootview = v.getRootView();
rootview.setDrawingCacheEnabled(true);
Bitmap bitmap1 = rootview.getDrawingCache();
return bitmap1;
}
public void createImage(Bitmap bmp) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 40, bytes);
File file = new File(Environment.getExternalStorageDirectory() +
"/capturedscreenandroid.jpg");
try {
file.createNewFile();
FileOutputStream outputStream = new FileOutputStream(file);
outputStream.write(bytes.toByteArray());
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Add Permission to read and write external storage
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
In my app I have an imageview on screen "A" and a webview on screen "B".
On screen "A" I start an sync task in order to download and show a png file into the imageview.
On screen "B" I load some HTML info. in which the link to the same png on screen "A" is included.
The problem is that the same image looks different on both screens. When loaded in the imageview, the png looks way smaller than when it is loaded in the webview.
The height and the width of the imageview are set to wrap_content. There is no additional scaling or something similar.
Why is this happening?
---EDIT---
screen "A" layout
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/background_repeat">
<ImageView
android:id="#+id/logo_image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_gravity="center_horizontal"/>
</RelativeLayout>
screen "B" layout
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<WebView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/about_us_web_view"
/>
</RelativeLayout>
screen "A" asyncTask
private class DownloadLogoTask extends AsyncTask<ImageView, String, Bitmap> {
private String urlString;
public DownloadLogoTask(String urlString) {
this.urlString = urlString;
}
#Override
protected Bitmap doInBackground(ImageView... imageViews) {
try {
URL url = new URL(urlString);
HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
InputStream is = urlConnection.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(is);
if(bitmap != null) {
return bitmap;
}
} catch (Exception e) {
}
return null;
}
#Override
protected void onPostExecute(Bitmap result) {
if(result != null) {
logoImageView.setImageBitmap(result);
}
}
}
screen "B" usage of the webView
aboutUsWebView.loadData(descriptionStr, "text/html", "UTF-8");
I'm trying to read an image from external storage as an OpenCV Mat file, convert it to a bitmap image and then display the image (review image after picture is taken). After debugging, it looks like everything is working except the setImageBitmap part. Please let me know what I might be doing wrong. Thanks!
public boolean onTouch(View v, MotionEvent event) {
Mat img = Highgui.imread(Environment.getExternalStorageDirectory().getPath() + "/sample_picture_2015-06-09_13-24-53.jpeg");
displayBitmap(img);
return false;
}
public void displayBitmap(Mat img){
Bitmap bm = Bitmap.createBitmap(img.cols(), img.rows(),Bitmap.Config.ARGB_8888);
Utils.matToBitmap(img, bm);
// find the imageview and draw it!
ImageView iv = (ImageView) findViewById(R.id.imageView1);
iv.setImageBitmap(bm);
Log.i(TAG, "Here");
}
And here is my xml file
<LinearLayout 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" >
<org.opencv.samples.tutorial3.Tutorial3View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:id="#+id/tutorial3_activity_java_surface_view" />
<ImageView
android:id="#+id/imageView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="2dp"/>
</LinearLayout>
Though it's too late, maybe will help others,
In your onTouch,
File imgFile = new File(Environment.getExternalStorageDirectory()+imgName);
if (imgFile.exists()) {
myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
Mat img = new Mat(myBitmap.getHeight(), myBitmap.getWidth(),
CvType.CV_8UC4);
displayBitmap(img);
Now it should work!
So I am loading images from URLs with this method
public Drawable loadImage(String url) {
try {
InputStream is = (InputStream) new URL(url).getContent();
Drawable d = Drawable.createFromStream(is, "src name");
return d;
} catch (Exception e) {
System.out.println(e.getMessage()+" oh noo ");
return null;
}
}
But I want the image's width to be the same as its parent (that is the root element with height and width 100%). I couldn't find a way to do it using only XML. It always leaves paddings on the edges. And I found out it is because the image doesn't have the same ratio of the screen. screen is, for example 16:9 and image is 4:3. Android will make paddings to fill this difference.
Do you know how can I do it programmatically when I load the image? And I need this image to remain as big as the screen's width even when the device rotates (so I think I will need to calculate it gain)
I am using this code to get the size of the screen
public Size getScreenSize(){
Size screenSize = new Size();
DisplayMetrics metrics = new DisplayMetrics();
this.activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
screenSize.height = metrics.heightPixels;
screenSize.width = metrics.widthPixels;
return screenSize;
}
public class Size{
public double height;
public double width;
}
#EDIT1
This is how I insert the drawable in the View. The view is already declared in the activity's XML
ImageView picture = (ImageView) findViewById(R.id.picture);
picture.setImageDrawable(loadImage(url));
#EDIT2
this is how I wrote the activity layout and its style
<LinearLayout 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:orientation="vertical"
tools:context=".MainActivity" >
<!-- style="#style/globalHeader" -->
<LinearLayout
style="#style/globalHeader"
>
<TextView
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#fff"
android:textSize="18sp"
android:textStyle="bold"
/>
<TextView
android:id="#+id/subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#fff"
android:textSize="14sp"
/>
</LinearLayout>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/picture"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:background="#f00"
>
</ImageView>
<TextView
android:id="#+id/desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="20dp"
/>
<TextView
android:id="#+id/details"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
This is the appearance I want to achieve
https://docs.google.com/a/uniriotec.br/file/d/0B2abPynX9PhkODhRVEkwcUphY28/edit?pli=1
I think so this is the one you are finding for.
just rescale the image of drawable taken from internet.
Bitmap bit = BitmapFactory.decodeResource(getApplicationContext()
.getResources(), drawable);
if (bit != null) {
Bitmap resizedBitmap = Bitmap.createScaledBitmap(bit, width,
height, true);
imageView.setBitmap(resizedBitmap);
}
the width and height are calculated below
DisplayMetrics disp = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(disp);
int width = disp.widthPixels;
int height = disp.heightPixels;
#EDIT
private Bitmap loadImage(String URL)
{
Bitmap bitmap = null;
InputStream in = null;
try {
in = OpenHttpConnection(URL);
bitmap = BitmapFactory.decodeStream(in);
in.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return bitmap;
}
private InputStream OpenHttpConnection(String urlString)
throws IOException
{
InputStream in = null;
int response = -1;
URL url = new URL(urlString);
URLConnection conn = url.openConnection();
if (!(conn instanceof HttpURLConnection))
throw new IOException("Not an HTTP connection");
try{
HttpURLConnection httpConn = (HttpURLConnection) conn;
httpConn.setAllowUserInteraction(false);
httpConn.setInstanceFollowRedirects(true);
httpConn.setRequestMethod("GET");
httpConn.connect();
response = httpConn.getResponseCode();
if (response == HttpURLConnection.HTTP_OK)
{
in = httpConn.getInputStream();
}
}
catch (Exception ex)
{
throw new IOException("Error connecting");
}
return in;
}
Directly take the bitmap image and rescale it and use it.
Not sure how will it behave with device rotation, but I believe you actually can do it from your xml layout, setting your ImageView.ScaleType to CENTER_CROP should do the trick.-
CENTER_CROP : Scale the image uniformly (maintain the image's aspect ratio) so that both dimensions (width and height) of the image will be equal to or larger than the corresponding dimension of the view (minus padding).
<ImageView
android:id="#+id/picture"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop" />
Try this
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:id="#+id/picture"
android:scaleType="fitXY"
android:background="#f00"
>
i want to create a Frame layout to place a number of images from database, which need to be a horizontal scrollable list. Image Views are creating dynamically based on database value. Images must be overlapped like the attachment . Here is my xml
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:layout_marginTop="20dp"
>
<FrameLayout
android:id="#+id/frmLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:scrollbars="horizontal"
android:layout_weight="1"
>
</FrameLayout>
</HorizontalScrollView>
and Here is java
public void getAllImages(){
cursorImages = dbAdapter.fetchImages();
if (cursorImages.moveToFirst()) {
BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize = 2;
do {
String filename = cursorImages.getString(cursorImages
.getColumnIndex("filename"));
try {
InputStream ims = getAssets().open("images/" + filename);
Bitmap bm = BitmapFactory.decodeStream(ims,null,options);
Matrix mat = new Matrix();
mat.postRotate(30);
Bitmap bMapRotate = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), mat, true);
ImageView im = new ImageView (this);
im.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
im.setImageBitmap(bMapRotate);
frmLayout.addView(im,new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
} catch (IOException ex) {
}
} while (cursorImages.moveToNext());
}
cursorImages.close();
}