I record a video from Samsung Galaxy S4 (1080wx1920h) from FRONT CAMERA.
The resulting video is rotated 90° and upside down. (See the picture)
Then I take the video (final resolution 320wx240h) and I display it to TextureView with:
textureView.setRotation(90.0f);
textureView.setScaleX(-1);
and I set the layout parameters of the textureView to:
ViewGroup.LayoutParams params = textureView.getLayoutParams();
params.height = 1440;
params.width = 1080;
textureView.setLayoutParams(params);
The result looks like:
After several retries I figgured that if I set layout to:
params.height = 810;
params.width = 1080;
The dimensions ration remains correct:
Finally I would like to display the video as it was recorded in RecordingActivity (1080wx1440h):
Any thoughts on how to accomplish this?
Or is there a way how to record the video from front camera in correct rotation?
Full activity code:
import android.app.Activity;
import android.graphics.Point;
import android.graphics.SurfaceTexture;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.Display;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Surface;
import android.view.TextureView;
import android.view.ViewGroup;
public class ReplayActivity extends Activity implements TextureView.SurfaceTextureListener {
private String pathToVideo;
private TextureView textureView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_replay);
textureView = (TextureView)findViewById(R.id.texture_view);
textureView.setSurfaceTextureListener(this);
textureView.setRotation(90.0f);
textureView.setScaleX(-1);
pathToVideo = getIntent().getStringExtra("path");
}
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setSurface(new Surface(surface));
try {
mediaPlayer.setDataSource(pathToVideo);
mediaPlayer.prepare();
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);//x = 1080, y = 1920
Point videoDimensions = new Point(mediaPlayer.getVideoWidth(),mediaPlayer.getVideoHeight());//x = 320, y = 240
Point resultParams = VideoHelpers.getScaledDimension(new Point(videoDimensions.y * 1000, videoDimensions.x * 1000), size);//x = 1080, y = 1440
ViewGroup.LayoutParams params = textureView.getLayoutParams();
params.height = resultParams.y;//1440
params.width = resultParams.x;//1080
textureView.setLayoutParams(params);
mediaPlayer.start();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {return false;}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, int height) {}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {}
}
XML:
<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:background="#FF0000">
<TextureView
android:id="#+id/texture_view"
android:layout_width="wrap_content"
android:background="#000000"
android:layout_height="wrap_content" />
</RelativeLayout>
Playing with the camera, the previews, the textures, adn the matrix can be tricky.
Have in mind that the natural orientation of the camera is landscape, so if you dont do anything else, the resulting video will be in that orientation. Also, the preview frames will be landscape.
when you do textureView.setRotation(90.0f); and textureView.setScaleX(-1); you are only modifying the internal transformation matrix of the texture, this is, when something is drawed inside, a transformation occurs, and what you see is different of the actual content. This is fine, but actually the camera dont know anything about this rotation and neither the mediarecorder.
If you are using Mediarecorder You should take a look at
MediaRecorder.html#setOrientationHint(int)
Sets the orientation hint for output video playback. This method
should be called before prepare(). This method will not trigger the
source video frame to rotate during video recording, but to add a
composition matrix containing the rotation angle in the output video
if the output format is OutputFormat.THREE_GPP or OutputFormat.MPEG_4
so that a video player can choose the proper orientation for playback.
Note that some video players may choose to ignore the compostion
matrix in a video during playback.
Parameters
degrees the angle to be rotated clockwise in degrees. The
supported angles are 0, 90, 180, and 270 degrees.
If you are using other recording approach, probably you shold take a look at
Camera.Parameters.html#setRotation(int)
or
Camera.html#setDisplayOrientation(int)
Related
I am working on an Android application with an embedded QR code scanner using the Google Vision API. The scanner functions, but the SurfaceView that acts as camera preview is stretched vertically. The degree of distortion is different for different emulated devices.
As I understand it, you would use mCameraSource.setRequestedPreviewSize(w,h) to set the correct size. w and h I have set as Resources.getSystem().getDisplayMetrics().widthPixels and Resources.getSystem().getDisplayMetrics().heightPixels, respectively. However, I have noticed that regardless of what numbers I parse as width and height, there are no changes in the way it displays.
However, resizing the SurfaceView on which it is displayed does have an effect on the distortion. For one particular emulated Android device I can statically set the right width and height. For different devices, however, with a slightly different pixel w:h ratio, the distortion can become quite large.
I have read various solutions on StackOverflow, but most use the CameraPreview instead of the CameraSource.Builder.
My code thus far is (part of ScannerActivity.java):
private SurfaceView svCamera;
private BarcodeDetector barcodeDetector;
private CameraSource cameraSource;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scanner);
initViews();
initListeners();
barcodeDetector = new BarcodeDetector.Builder(this)
.setBarcodeFormats(Barcode.QR_CODE)
.build();
cameraSource = new CameraSource.Builder(this, barcodeDetector)
.setRequestedPreviewSize(Resources.getSystem().getDisplayMetrics().widthPixels, Resources.getSystem().getDisplayMetrics().heightPixels)
.setAutoFocusEnabled(true)
.build();
svCamera.getHolder().addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
requestPermission();
try {
if (ActivityCompat.checkSelfPermission(ScannerActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
return;
}
cameraSource.start(svCamera.getHolder());
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
cameraSource.stop();
}
});
barcodeDetector.setProcessor(new Detector.Processor<Barcode>() {
#Override
public void release() {
scanned = true;
}
#Override
public void receiveDetections(Detector.Detections<Barcode> detections) {
...
}
});
} }
Can someone help me with setting preview size?
The way I fixed it with help of Alex Cohn's answer:
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int width = displayMetrics.widthPixels;
int height = displayMetrics.heightPixels;
...
cameraSource.setRequestedPreviewSize(1280, 720); // Hardcoded, for now.
And I set the size of the SurfaceView with:
svCamera.setLayoutParams(new RelativeLayout.LayoutParams(width, width/9*16));
If I remember I will update this to a non-hardcoded version.
Quite contrary. You cannot choose arbitrary resolution for setRequestedPreviewSize(). This CameraSource API wraps the ordinary Camera API, which exposes only some, "supported" pairs of width and height.
If you want to display the live view undistorted, you must setup your SurfaceView to match the aspect ratio of chosen camera preview. This means, it's OK to use surface of 320x240 pixel for camera 640x480. It's even OK to use surface of 1280x720 for camera 1920x1080.
But if you have surface of 800x480 for camera of 1280x720 (and if your devices supports such camera resolution), the picture will be slightly stretched.
I need to make an ImageView slide from left to right of the screen with a smooth animation (I want the ImageView to be visible during the transition) I tried with the following code:
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
camion.animate()
.translationX(width)
.setDuration(2000)
.setInterpolator(new LinearInterpolator())
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
//camion.setVisibility(View.GONE);
}
});
The ImageView moves but the animation is laggy and not smooth like I want to.
What am I doing wrong on the code?
Creating this kind of tween animation is simple. Just follow the steps,
Step 1
Create a directory anim inside the res directory and put this as slide.xml
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator"
android:fillAfter="true">
<translate
android:fromXDelta="0%p"
android:toXDelta="75%p"
android:duration="800" />
</set>
You can obviously customize the animation by changing the two attributes fromXDelta and toXDelta. The %p refers to with respect to the parent which simply means that it will move the image 75% with respect to the parent.
Step 2
// Refer the ImageView like this
imageView = (ImageView) findViewById(R.id.img);
// Load the animation like this
animSlide = AnimationUtils.loadAnimation(getApplicationContext(),
R.anim.slide);
// Start the animation like this
imageView.startAnimation(animSlide);
You can also setInterpolator() and setListeners() if you want to. I haven't shown them here to keep it simple. If you need, just let me know.
NOTE
As you have mentioned repeatedly, that you are experiencing a laggy animation. I have tested this animation on 3 real devices and 2 emulators and the animation was buttery smooth on all of them. Tested on low end devices like Moto E to high end devices like Nexus 5 and Galaxy S6.
If you still have a lag running this code, then the test device must be the reason. The code is perfect.
UPDATE
I just checked on my Moto G running on Lollipop too, the animation is running smoothly. This is a very small and light-weight animation, and should never be laggy. If you are still getting a lag, then it must be the device you are testing, or some other piece of code on that Activity making the UI slow or unresponsive.
Try to check which one is applicable to you,
I have tested on a total of 6 devices now with no lag at all. So, you can be rest assured that your production app will not have any lag, it can be your device which is slow
If you are doing some heavy operations like accessing the file system, database, or any other heavy operation, it must be slowing down the UI thread and you are loosing frames. Try to use AsyncTask for these heavy operations
Try this. It will animate the imageview.
ImageView img_animation = (ImageView) findViewById(R.id.img_animation);
Display display = getWindowManager().getDefaultDisplay();
float width = display.getWidth();
TranslateAnimation animation = new TranslateAnimation(0, width - 50, 0, 0); // new TranslateAnimation(xFrom,xTo, yFrom,yTo)
animation.setDuration(1000); // animation duration
animation.setRepeatCount(5); // animation repeat count
animation.setRepeatMode(2); // repeat animation (left to right, right to
// left )
// animation.setFillAfter(true);
img_animation.startAnimation(animation); // start animation
TranslateAnimation animate = new TranslateAnimation(0, -view.getWidth(), 0, 0);
animate.setDuration(500);
animate.setFillAfter(true);
view.startAnimation(animate);
Hope this works for u
animation.xml
<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"
tools:context=".Animation" >
<ImageView
android:id="#+id/img_animation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:layout_marginTop="42dp"
android:src="#drawable/emo_im_laughing" />
</RelativeLayout>
Animation.java
import android.os.Bundle;
import android.app.Activity;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
public class Animation extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.);
ImageView img_animation = (ImageView) findViewById(R.id.img_animation);
TranslateAnimation animation = new TranslateAnimation(0.0f, 400.0f,
0.0f, 0.0f);
animation.setDuration(5000);
animation.setRepeatCount(5);
animation.setRepeatMode(2);
animation.setFillAfter(true);
img_animation.startAnimation(animation);
}
}
try the code below
TranslateAnimation animation = new TranslateAnimation(0.0f, 0.0f, 0.0f, 1500.0f); // new TranslateAnimation (float fromXDelta,float toXDelta, float fromYDelta, float toYDelta)
animation.setDuration(2000); // animation duration
animation.setRepeatCount(1); // animation repeat count if u repeat only once set to 1 if u don't repeat set to 0
animation.setFillAfter(false);
your_view .startAnimation(animation);//your_view for mine is imageView
public class MainActivity extends Activity {
int windowwidth;
int windowheight;
private LayoutParams layoutParams;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
windowwidth = getWindowManager().getDefaultDisplay().getWidth();
windowheight = getWindowManager().getDefaultDisplay().getHeight();
final ImageView img = (ImageView) findViewById(R.id.imageView1);
img.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
LayoutParams layoutParams = (LayoutParams) img
.getLayoutParams();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
int x_cord = (int) event.getRawX();
int y_cord = (int) event.getRawY();
if (x_cord > windowwidth) {
x_cord = windowwidth;
}
if (y_cord > windowheight) {
y_cord = windowheight;
}
layoutParams.leftMargin = x_cord - 25;
layoutParams.topMargin = y_cord - 75;
img.setLayoutParams(layoutParams);
break;
default:
break;
}
return true;
}
});
}
}
To Move imageview
from Right to Left Using #Aritra Roy Answer.
Use this code
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator"
android:fillAfter="true">
<translate
android:fromXDelta="75%p"
android:toXDelta="0%p"
android:duration="100000" />
</set>
Now we have MotionLayout try to use that for very clean and smooth sliding animation.
What is the best way to blur background images like the image below? I saw some code and libraries but their are a couple of years old or like BlurBehind library, but it doesn't give the same effect.
The easiest way to do that is use a library. Take a look at this one: https://github.com/wasabeef/Blurry
With the library you only need to do this:
Blurry.with(context)
.radius(10)
.sampling(8)
.color(Color.argb(66, 255, 255, 0))
.async()
.onto(rootView);
This is an easy way to blur Images Efficiently with Android's RenderScript that I found on this article
Create a Class called BlurBuilder
public class BlurBuilder {
private static final float BITMAP_SCALE = 0.4f;
private static final float BLUR_RADIUS = 7.5f;
public static Bitmap blur(Context context, Bitmap image) {
int width = Math.round(image.getWidth() * BITMAP_SCALE);
int height = Math.round(image.getHeight() * BITMAP_SCALE);
Bitmap inputBitmap = Bitmap.createScaledBitmap(image, width, height, false);
Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap);
RenderScript rs = RenderScript.create(context);
ScriptIntrinsicBlur theIntrinsic = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap);
Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap);
theIntrinsic.setRadius(BLUR_RADIUS);
theIntrinsic.setInput(tmpIn);
theIntrinsic.forEach(tmpOut);
tmpOut.copyTo(outputBitmap);
return outputBitmap;
}
}
Copy any image to your drawable folder
Use BlurBuilder in your activity like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_login);
mContainerView = (LinearLayout) findViewById(R.id.container);
Bitmap originalBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.background);
Bitmap blurredBitmap = BlurBuilder.blur( this, originalBitmap );
mContainerView.setBackground(new BitmapDrawable(getResources(), blurredBitmap));
Renderscript is included into support v8 enabling this answer down to api 8. To enable it using gradle include these lines into your gradle file (from this answer)
defaultConfig {
...
renderscriptTargetApi *your target api*
renderscriptSupportModeEnabled true
}
Result
You can use:
Glide.with(getContext()).load(R.mipmap.bg)
.apply(bitmapTransform(new BlurTransformation(22)))
.into((ImageView) view.findViewById(R.id.imBg));
This requires the following addition to your build.gradle file:
implementation 'jp.wasabeef:glide-transformations:4.0.0'
The simplest way to achieve this is given below,
I)
Glide.with(context.getApplicationContext())
.load(Your Path)
.override(15, 15) // (change according to your wish)
.error(R.drawable.placeholder)
.into(image.score);
else you can follow the code below..
II)
1.Create a class.(Code is given below)
public class BlurTransformation extends BitmapTransformation {
private RenderScript rs;
public BlurTransformation(Context context) {
super( context );
rs = RenderScript.create( context );
}
#Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
Bitmap blurredBitmap = toTransform.copy( Bitmap.Config.ARGB_8888, true );
// Allocate memory for Renderscript to work with
Allocation input = Allocation.createFromBitmap(
rs,
blurredBitmap,
Allocation.MipmapControl.MIPMAP_FULL,
Allocation.USAGE_SHARED
);
Allocation output = Allocation.createTyped(rs, input.getType());
// Load up an instance of the specific script that we want to use.
ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
script.setInput(input);
// Set the blur radius
script.setRadius(10);
// Start the ScriptIntrinisicBlur
script.forEach(output);
// Copy the output to the blurred bitmap
output.copyTo(blurredBitmap);
toTransform.recycle();
return blurredBitmap;
}
#Override
public String getId() {
return "blur";
}
}
2.Set image to ImageView using Glide.
eg:
Glide.with(this)
.load(expertViewDetailsModel.expert.image)
.asBitmap()
.transform(new BlurTransformation(this))
.into(ivBackground);
Android 12, Preview 1 comes with built-in blur feature. We need not depend on external library now. Here is the code
imageView.setRenderEffect(
RenderEffect.createBlurEffect(
20.0f, 20.0f, SHADER_TITLE_MODE
)
)
Works only on Android 12 as of now so is not a universal solution yet
To blur a image
1 Set your target SDK and compile SDK to Android S in build.gradle
2.Use Render Effect
3.set blur as follows
your_view.setRenderEffect(
RenderEffect.createBlurEffect(
30f, //radius X
30f, //Radius Y
Shader.TileMode.[X]// X=CLAMP,DECAL,MIRROR,REPEAT
)
4.The 4 types of blend mode are
CLAMP- Replicate the edge color if the shader draws outside of its original bounds
DECAL- Render the shader's image pixels only within its original bounds
MIRROR- Repeat the shader's image horizontally and vertically, alternating mirror images so that adjacent images always seam.
REPEAT - Repeat the shader's image horizontally and vertically.
This worked for me. Tested on Android 9 and 12. Use Glide library to shrink the bitmap.
// Glide
implementation 'com.github.bumptech.glide:glide:4.13.0'
kapt 'com.github.bumptech.glide:compiler:4.13.0'
Glide.with(context).asBitmap().load(favorite.coverImage).into(object : CustomTarget<Bitmap>(2, 2) {
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
ivContentHolder.setImageDrawable(BitmapDrawable(itemBinding.root.context.resources, resource))
}
override fun onLoadCleared(placeholder: Drawable?) {
ivContentHolder.setImageDrawable(null)
}
CustomTarget(2, 2) is the trick. The lower the value the more the blur effect. Basically its used to shrink the image size. Then all you have to do is set the shrunk bitmap to your imageView. And most important is to set ScaleType of the imageView to CenterCrop.
<ImageView
android:id="#+id/iv_content_holder"
android:layout_width="match_parent"
android:layout_height="96dp"
android:scaleType="centerCrop"
android:src="#color/purple_700"
app:layout_constraintBottom_toBottomOf="parent" />
The result will look something like this. Blur Effect Demo
this might not be the most efficient solution but I had to use it since the wasabeef/Blurry library didn't work for me. this could be handy if you intend to have some getting-blurry animation:
1- you need to have 2 versions of the picture, normal one and the blurry one u make with photoshop or whatever
2- set the images fit on each other in your xml, then one of them could be seen and that's the upper one
3- set fadeout animation on the upper one:
final Animation fadeOut = new AlphaAnimation(1, 0);
fadeOut.setInterpolator(new AccelerateInterpolator());
fadeOut.setDuration(1000);
fadeOut.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {}
#Override
public void onAnimationEnd(Animation animation) {upperone.setVisibility(View.GONE);}
#Override
public void onAnimationRepeat(Animation animation) {}
});
upperone.startAnimation(fadeOut);
you can use Glide for load and transform into blur image,
1) for only one view,
val requestOptions = RequestOptions()
requestOptions.transform(BlurTransformation(50)) // 0-100
Glide.with(applicationContext).setDefaultRequestOptions(requestOptions)
.load(imageUrl).into(view)
2) if you are using the adapter to load an image in the item, you should write your code in the if-else block, otherwise, it will make all your images blurry.
if(isBlure){
val requestOptions = RequestOptions()
requestOptions.transform(BlurTransformation(50))
Glide.with(applicationContext).setDefaultRequestOptions(requestOptions)
.load(imageUrl).into(view )
}else{
val requestOptions = RequestOptions()
Glide.with(applicationContext).setDefaultRequestOptions(requestOptions).load(imageUrl).into(view)
}
Android 12 (Api level 31) has new Theme parameters to apply for windows to blur background:
<style name="BlurryTheme" parent="...">
<item name="android:windowBackgroundBlurRadius">30dp</item>
<item name="android:windowBlurBehindEnabled">true</item>
<item name="android:windowBlurBehindRadius">10dp</item>
</style>
And also new API for View to apply blur effect android.view.View#setRenderEffect:
imageView.setRenderEffect(
RenderEffect.createBlurEffect(
20.0f, 20.0f, Shader.TileMode.CLAMP
)
)
You can have a view with Background color as black and set alpha for the view as 0.7 or whatever as per your requirement.
<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/onboardingimg1">
<View
android:id="#+id/opacityFilter"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/black"
android:layout_alignParentBottom="true"
android:alpha="0.7">
</View>
</RelativeLayout>
Try below code..
Put This Code in On Create..
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy =
new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
Url="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTIur0ueOsmVmFVmAA-SxcCT7bTodZb3eCNbiShIiP9qWCWk3mDfw";
// Picasso.with(getContext()).load(Url).into(img_profile);
// Picasso.with(getContext()).load(Url).into(img_c_profile);
bitmap=getBitmapFromURL(Url);
Bitmap blurred = blurRenderScript(bitmap, 12);//second parametre is radius
img_profile.setImageBitmap(blurred);
Create Below Methods.. Just Copy Past..
public static Bitmap getBitmapFromURL(String src) {
try {
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
} catch (IOException e) {
// Log exception
return null;
}
}
#SuppressLint("NewApi")
private Bitmap blurRenderScript(Bitmap smallBitmap, int radius) {
try {
smallBitmap = RGB565toARGB888(smallBitmap);
} catch (Exception e) {
e.printStackTrace();
}
Bitmap bitmap = Bitmap.createBitmap(
smallBitmap.getWidth(), smallBitmap.getHeight(),
Bitmap.Config.ARGB_8888);
RenderScript renderScript = RenderScript.create(getActivity());
Allocation blurInput = Allocation.createFromBitmap(renderScript, smallBitmap);
Allocation blurOutput = Allocation.createFromBitmap(renderScript, bitmap);
ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(renderScript,
Element.U8_4(renderScript));
blur.setInput(blurInput);
blur.setRadius(radius); // radius must be 0 < r <= 25
blur.forEach(blurOutput);
blurOutput.copyTo(bitmap);
renderScript.destroy();
return bitmap;
}
private Bitmap RGB565toARGB888(Bitmap img) throws Exception {
int numPixels = img.getWidth() * img.getHeight();
int[] pixels = new int[numPixels];
//Get JPEG pixels. Each int is the color values for one pixel.
img.getPixels(pixels, 0, img.getWidth(), 0, 0, img.getWidth(), img.getHeight());
//Create a Bitmap of the appropriate format.
Bitmap result = Bitmap.createBitmap(img.getWidth(), img.getHeight(), Bitmap.Config.ARGB_8888);
//Set RGB pixels.
result.setPixels(pixels, 0, result.getWidth(), 0, 0, result.getWidth(), result.getHeight());
return result;
}
This might be a very late reply but I hope it helps someone.
You can use third party libs such as RenderScript/Blurry/etc.
If you do not want to use any third party libs, you can do the below using alpha(setting alpha to 0 means complete blur and 1 means same as existing).
Note(If you are using point 2) : While setting alpha to the background, it will blur the whole layout. To avoid this, create a new xml containing drawable and set alpha here to 0.5 (or value of your wish) and use this drawable name (name of file) as the background.
For example, use it as below (say file name is bgndblur.xml):
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:shape="rectangle"
android:src="#drawable/registerscreenbackground"
android:alpha="0.5">
Use the below in your layout :
<....
android:background="#drawable/bgndblur">
Hope this helped.
You can quickly get to blur effect by doing the following.
// Add this to build.gradle app //
Compile ' com.github.jgabrielfreitas:BlurImageView:1.0.1 '
// Add to XML
<com.jgbrielfreitas.core.BlurImageView
android:id="#+id/iv_blur_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
//Add this to java
Import com.jgabrielfreitas.core.BlueImageView;
// Under public class *activity name * //
BlurImageView myBlurImage;
// Under Oncreate//
myBlurImage = (ImageView) findViewById(R.id.iv_blur_image)
MyBlurImage.setBlue(5)
I hope that helps someone
So we want to make a game in which we move a balloon with an Android phone's accelerometer. There will be obstacles probably created using ImageView's that cause the balloon to pop when they collide. So far, we got the ImageView balloon to move, but it seems as though the drawable (called yellow_balloon) is only able to be seen INSIDE the ImageView balloon's layout.
The java code:
package com.ec327.ballon;
import android.os.Bundle;
import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.util.Log;
public class GameScreen extends Activity implements SensorEventListener {
private ImageView balloon=null;
final String tag = "AccLogger";
SensorManager sensore=null;
int xa=0;
int ya=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.game_screen);
sensore = (SensorManager) getSystemService(SENSOR_SERVICE);
balloon = (ImageView)findViewById(R.id.balloon);
balloon.scrollTo(xa, ya);
//balloon.offsetLeftAndRight(50);
//balloon.offsetTopAndBottom(50);
//balloon.setImageResource(R.drawable.yellow_balloon);
}
public void onSensorChanged(SensorEvent event){
Sensor sensor = event.sensor;
float [] values = event.values;
synchronized (this) {
Log.d(tag, "onSensorChanged: " + sensor + ", x: " +
values[0] + ", y: " + values[1] + ", z: " + values[2]);
if (sensor.getType() == Sensor.TYPE_ACCELEROMETER ) {
xa=(int)values[0];// this part of code is only test to see int x and y on Activity
ya=(int)values[1];
}
}
balloon.scrollBy(xa, ya);
balloon.invalidate();
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
Log.d(tag,"onAccuracyChanged: " + sensor + ", accuracy: " + accuracy);
}
protected void onResume() {
super.onResume();
Sensor Accel = sensore.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
// register this class as a listener for the orientation and accelerometer sensors
sensore.registerListener((SensorEventListener) this, Accel, SensorManager.SENSOR_DELAY_FASTEST);
}
}
The XML code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#drawable/blank_screen">
<ImageView
android:id="#+id/balloon"
android:layout_width="41dp"
android:layout_height="142dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:adjustViewBounds="true"
android:src="#drawable/yellow_balloon" />
</RelativeLayout>
In the xml file, ImageView balloon has a layout_width=41dp and layout_height=142dp. When the program runs, the yellow_balloon moves around, but once it moves outside the layout dimensions of ImageView balloon, it can't be seen anymore.
Does scrollBy() only move the drawable yellow_balloon and not the actual balloon layout's position? We've tried using that as well as layout.setMargins, but neither are working. We've also tried using setOffsetTopAndBottom and setOffsetLeftAndRight, but that does not move the ImageView of the balloon. What's causing this problem and how do we fix it?
I am not entirely sure using imageViews is the easiest or most efficient way of doing what you are doing, especially if you want to create obstacles for the balloon to collide into and pop.
My suggestion would be that your game is done entirely inside of a SurfaceView. From here you would be able to add in "Sprites" which would be all of your objects (your Balloon, your obstacles) and you can have it check for sprite collisions (your cases where the balloon would pop).
The problem with imageviews is that you are going to need to move the entire image and once you are introducing multiple images, unless the box around the image is entirely full with the picture you will begin to get picture overlaps or collisions before the actual collision occurs.
I am trying with no success to modify the code example from:
http://www.inter-fuser.com/2009/08/android-animations-3d-flip.html
so it will rotate the images in a loop, when clicking on the image once. (second click should pause).
I tried using Handler and threading but cannot update the view since only the main thread can update UI.
Exception I get from the code below:
android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
[in 'image1.startAnimation(rotation);' ('applyRotation(0, 90);' from the main thread)]
package com.example.flip3d;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.widget.ImageView;
public class Flip3d extends Activity {
private ImageView image1;
private ImageView image2;
private boolean isFirstImage = true;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
image1 = (ImageView) findViewById(R.id.image01);
image2 = (ImageView) findViewById(R.id.image02);
image2.setVisibility(View.GONE);
image1.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
if (isFirstImage) {
applyRotation(0, 90);
isFirstImage = !isFirstImage;
} else {
applyRotation(0, -90);
isFirstImage = !isFirstImage;
}
}
});
}
private void applyRotation(float start, float end) {
// Find the center of image
final float centerX = image1.getWidth() / 2.0f;
final float centerY = image1.getHeight() / 2.0f;
// Create a new 3D rotation with the supplied parameter
// The animation listener is used to trigger the next animation
final Flip3dAnimation rotation =
new Flip3dAnimation(start, end, centerX, centerY);
rotation.setDuration(500);
rotation.setFillAfter(true);
rotation.setInterpolator(new AccelerateInterpolator());
rotation.setAnimationListener(new DisplayNextView(isFirstImage, image1, image2));
if (isFirstImage)
{
image1.startAnimation(rotation);
} else {
image2.startAnimation(rotation);
}
}
}
How can I manage to update the UI and control the rotation within onClick listener?
Thank you,
Oakist
Try wrapping the UI code in runOnUIThread()