I've been looking for something about adding images to videos, but i haven't found what I wanted.
I'd like to add a bitmap/image mask in each frame of a video (it can be recorded or from SD), keeping the original sound, and save the video to the SD with the image.
Someone knows how it can be done in Android?
Thnx
create a class that extends SurfaceView
public class PaintSurface extends SurfaceView {
....
In draw() function add code
#Override
public void draw(Canvas canvas) {
super.draw(canvas);
canvas.drawBitmap(bitmap.img, bitmapPosX, bitmapPosY, null);
}
}
In onCreate function create an object of it.
videoView = new PaintSurface(this);
add it to your layout
RelativeLayout layut = (RelativeLayout) findViewById(R.id.lay);
layut.addView(videoView);
get a holder
videoHolder = videoView.getHolder();
set this holder's surface to the MediaRecorder object
recorder.setPreviewDisplay(videoHolder.getSurface());
Related
New Android programmer here.
I'm trying to display an .png image as a bitmap on Android. The only way I have been able to display the converted image at all is with a custom class that extends View. However, my image is too large to be displayed entirely on the screen and I would like to be able to scroll with it. But when I define a ScrollView and put the Canvas with the Bitmap into it, I get a blank screen. I had no luck setting this up with the layout file, so it is all done in the Activity class.
This is where the Activity is created:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ScrollView scroll = new ScrollView(this);
scroll.addView(new CustomView(this));
setContentView(scroll);
}
And this is my CustomView class:
private class CustomView extends View{
public CustomView(Context context) {
super(context);
}
#Override
protected void onDraw(Canvas canvas){
Bitmap bitmapMap = BitmapFactory.decodeResource(getResources(),R.drawable.resourceimage);
canvas.drawBitmap(bitmapMap,0,0,null);
this.setWillNotDraw(false);
}
}
And if I replace this line of code in my Activity: setContentView(scroll)
with this line: setContentView(new CustomView(this)), I can see the image, albeit not the entire image. So, is there a way to set this up in the layout files instead? Or is there something I'm missing that I need to declare in the ScrollView class?
EDIT: I would prefer not to use ImageView, because I would like to change the image in specific locations, and using bitmap seemed to be the easiest way to accomplish that, via x and y coordinates.
Your custom view needs to override the onMeasure method and properly set the measured width and height so that the parent views (in this case the ScrollView) can know how much space to allocate for the child.
My problem is that I don't know how to change position of a canvas drawable on click of
my button that it's located in the main activity and not to surfaceview so the code to work should be on surfaceview here is what I've got
public class JumpOnClick extends Activity implements OnClickListener{
DrawingSurface ds;
FrameLayout frm;
Button btnC;
int color=0xfff00000;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ds=new DrawingSurface(this);
setContentView(R.layout.activity_jump_on_click);
frm=(FrameLayout)findViewById(R.id.frameLayout);
frm.addView(ds);
btnC=(Button)findViewById(R.id.buttonColor);
btnC.setOnClickListener(this);
}
#Override
public void onClick(View v) {
// how to connect actions in here for my sprites on my surfaceview
// for example AnimatedSprite a = new AnimatedSprite();
// if(b == null)
//b=BitmapFactory.decodeStream(res.openRawResource(R.drawable.explosion));
// a.Initialize(b, 120, 159, 7, 20, true);
// mSprites.add(a);
}
}
if I understand correctly,
define two static float variables in your surfaceview class respectively x and y, and when you do your drawing in your surfaceview just use this variables as position parameters in your surfaceview's draw method. And then back in your activity in your onClick method of the button just change these x,y variables, as you can access them without any need to create object.
I believe that you need to add layout rules to your button to place it in the Surfaceview (Actually a button cant be added to a SurfaceView, you need to create an illusion with a Layout in your Activity and place the button to this Layout).
You can check this simple solution at this video https://www.youtube.com/watch?v=8qE9TQjQ5no&t=31s
that is placing buttons to a SurfaceView at the top and bottom using a Relativelayout. My opinion is with that technique you wont need the ontouchevent method neither the x,y position, you will need that if you create a button in the ondraw method (then wont be a button but a bitmap image)...My opinion is to stick with the first solution if the position is the problem so it can act as a button with the onclicklistener.
What I wanted to achieve is this:
I wanted to have a specific portion of the screen to be my SurfaceView. I will use this SurfaceView for some animations. But I wanted to include some Views like TextView and RadioButtonGroup beside my SurfaceView.
So my question is, is this possible? I looking for sample android source code about 'animating sprites', but I couldn't find any activity that incorporates both TextViews and SurfaceView. All are extending SurfaceView. If this is possible, how do I do it? Do you have sample source codes that I can try?
try this i am not extending surfaceview.
public class Preview_can_work extends Activity {
private SurfaceView surface_view;
SurfaceHolder.Callback sh_ob = null;
SurfaceHolder surface_holder = null;
SurfaceHolder.Callback sh_callback = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFormat(PixelFormat.TRANSLUCENT);
surface_view = new SurfaceView(getApplicationContext());
addContentView(surface_view, new LayoutParams(50, 50));
if (surface_holder == null) {
surface_holder = surface_view.getHolder();
}
sh_callback = my_callback(); // CREATING CALLBACK FOR YOUR SURFACE.
surface_holder.addCallback(sh_callback);
}
// THIS FUNCTION RETURNS CALLBACK OBJECT FOR SURFACEVIEW.
SurfaceHolder.Callback my_callback() {
SurfaceHolder.Callback ob1 = new SurfaceHolder.Callback() {
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
};
return ob1;
}
}
now you can simply add any textview or button on your layout it should work.
Note:- I am creating surface dynamically. In your case what you can do is you can create everything in xml file. Instead of creating surfaceview create video view.
SurfaceView surface_view = (SurfaceView) findViewById(R.id.video_view_id);
if you are fetch view by id from your layout then you have to remove some line from code. which are:
surface_view = new SurfaceView(getApplicationContext());
addContentView(surface_view, new LayoutParams(50, 50));
Hope it will help you...
It is definitely possible but you might need to present a little more information. If you want some simple animation to run next to the textview then you don't even need a surfaceview. Just create an imageview and run an animation on it (here is a tutorial I created for the very topic)
TextView and its kin DO NOT derive from Surfaceview they derive from the View class. Once again if you want to perform simple animations I don't think you will need a surfaceview. If you want to do more dynamic complex things then there is also a tutorial on my development blog on how to utilize a SurfaceView for a game. If that is more your flavor then you can create a custom surface view and then just tie it into your layout with the size dimensions you want.
I am attempting to create a user interface dynamically. I have successfully create a view and loaded my background image. I have created two additional small view items to display on the background. My problem is that I have not been able to find any advice/instruction that tells me how to draw the small views. It seems that it should be a trivial exercise and I am guessing it is just finding the correct referencing. Hope someone out there can point me in the right direction.
Here is my Activity:
public class GhostActivity extends Activity implements OnTouchListener
{
private DrawView ghostView;
public Card mCard1, mCard2;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
// ToDo add your GUI initialization code here
super.onCreate(savedInstanceState);
// requesting to turn the title OFF
requestWindowFeature(Window.FEATURE_NO_TITLE);
// making it full screen
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
ghostView = new DrawView(this);
setContentView(ghostView);
//get the window size
Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
Context context = getApplicationContext();
//create view items with initial positions
Point startPoint;
startPoint = new Point();
startPoint.x = 5;
startPoint.y = 3;
mCard1 = new Card(context, 1, R.drawable.bol_geel, startPoint);
startPoint.x = 5;
startPoint.y = 43;
mCard2 = new Card(context, 2, R.drawable.bol_rood, startPoint);
//now display them on the ghostView *****************HOW?
// set the callbacks
ghostView.setOnTouchListener(this);
mCard1.setOnTouchListener(this);
mCard2.setOnTouchListener(this);
}
and here is the View;
public class DrawView extends View
{
Drawable bg ;
public DrawView(Context context) {
super(context);
//setFocusable(true);
Drawable bg = this.getResources().getDrawable(R.drawable.bubbleblue480x800);
setBackgroundDrawable(bg);
}
#Override protected void onDraw(Canvas canvas) {
// canvas.drawColor(0x0000000); //if you want another background color
//draw on the canvas
}
}
edit: I believe my problem is needing to pass a pointer to the ghostView canvas. what makes me think that is if I create the children within ghostView then call their .draw method they appear exactly as I would expect.
#Override protected void onDraw(Canvas canvas) {
canvas.drawColor(0x0000000); //if you want another background color
//draw the cards on the canvas
mCard1.draw(canvas);
mCard2.draw(canvas);
}
so at this point I am wondering how to get a reference pointer to the ghostView canvas.
To be honest I am finding the whole Activity - View relationship confusing.
Edit: I have taken a different approach based on detail in this tutorial
http://www.kellbot.com/2009/06/android-hello-circle/
It uses a FrameLayout and it seems I can achieve my objective.
To add view dynamically to view your class must extends from ViewGroup or LinearLayout class then you will able to call method addView.
Inside your ghost view first add a layout e.g Linear or Relative. Then only you could able to add views inside that layout you cant simply add a view to a xml file.
Or you can create a dynamic layout then only u can add view inside that layout.
RelativeLayout relative= new RelativeLayout(findViewById(R.id.your relativeLayoutID));
relative.addView(child);
child could be anything button textview and widget.
I have subclassed the SurfaceView and instantiating it in onCreate of the Activity. The preview is generated but the control never enters onDraw() which is overriden in the subclass of SurfaceView. Why is that?
class ActivityClass extends Activity{
onCreate(){
mPreview = new Preview(this);
setContentView(mPreview);
}
public void startPreview(){
rec = new MediaRecorder();
rec.setVideoSource();.......
rec.setPreviewDisplay(mPreview.getSurfaceHolder.getSurface());
}
}
class Preview extends SurfaceView implements SurfaceHolder.Callback{
SurfaceHolder mHolder;
public Preview(Context context){
super(context);
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
bringToFront();//this is not
invalidate();//making a difference
}
SurfaceHolder getSurfaceHolder(){
return mHolder;
}
//Surface callback methods implemented here
}
Before drawing the preview on the Surface, shouldn't the control be given to the onDraw callback if it is implemented?
Because onDraw callback says to the Android framework 'you don't draw the view. I will draw it since I have been implemented'. Am I right?
Why then, is the control failing to enter onDraw()? Please help.
You simply have to add
setWillNotDraw(false)
To the constructor.
And its done..:)
public class SelectedRect extends View {
public SelectedRect(Context context) {
super(context);
bringToFront();
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawLine(canvas);
invalidate();
this.bringToFront();
}
}
And in activity class :
View rect = new SelectedRect(this);
rect.bringToFront();
this.addView(rect, new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
Something fishy is going on. It seems that you're trying to set the SurfaceView as a preview display. In that case, the Activity should implement SurfaceHolder.Callback (not the SurfaceView). This is so that the Activity can know when the SurfaceView has been created and is ready for drawing. Furthermore, it shouldn't even be necessary to extend SurfaceView: you should be able to user SurfaceView itself.
Assuming I misunderstood and you really want to extend surfaceview for some reason...
I don't see where you overrode onDraw in your Preview class. Did you not include this code?
When you say that the onDraw callback tells android 'you don't draw the view. I will draw it since I have been implemented', I disagree. onDraw is a function where a View draws stuff that all views have, such as the background. SurfaceView extends view. When you extend SurfaceView, you can override onDraw to tell android to draw stuff in addition to what the original onDraw in the View draws. In other words, Android always does all the drawing; overriding onDraw just tells it to draw a few more things when it's the right time to draw.