最近脑子一抽看了一个视频,说是合成Gif,就想玩一玩。事实证明就是脑抽。
上图
结构
就是上面的结构里的 gif 包下面的四个类。os:根本就没有用到下面两个类。
这是我找的,传到csdn上了,http://download.csdn.net/detail/chandelierr/9862589
这是跟着动脑学院的一个视频敲的。存在几个问题
播放的时候就自己保存了,所以仿佛保存按钮做不了什么。
有一个方法GifHelper.getGif(),GitHelper代码里没有我自己加上了。
/** * 解码GIF图片 * * @param is * @return */ public static GifFrame[] getGif(InputStream is) { GifHelper gifHelper = new GifHelper(); if (GifHelper.STATUS_OK == gifHelper.read(is)) { return gifHelper.getFrames(); } return null; }这代码那个老师没调出来,然后说了将近一个小时的广告,很尴尬。
package com.chandelier.gitmaker; public class MainActivity extends AppCompatActivity implements View.OnClickListener, TextWatcher { //这里随便找了个路径 File dest = new File("/storage/emulated/0/Tencent/TIMfile_recv/","dest"+Math.random()+".gif"); private static final String TAG = "MainActivity"; private static final int SELECT_IMAGE = 1; public static final int PLAY = 2; public static final int MAKEGIFANDPLAY = 3; String imagePath; GifHelper.GifFrame[] frames; GifHelper.GifFrame[] copyFrames; private Button select; private Button save; private EditText input; private ImageView gif_loc; private playThread pT ; //用于在主线程中播放 Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.what){ case PLAY: Bitmap bitmap = (Bitmap)msg.obj; gif_loc.setImageBitmap(bitmap); int time = msg.arg1; handler.postDelayed(pT,time); break; case MAKEGIFANDPLAY: if (pT != null){ handler.removeCallbacks(pT); } pT = new playThread(copyFrames); pT.start(); break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); select = (Button)findViewById(R.id.select); save = (Button)findViewById(R.id.save); input = (EditText)findViewById(R.id.input); gif_loc = (ImageView)findViewById(R.id.gif_loc); select.setOnClickListener(this); save.setOnClickListener(this); input.addTextChangedListener(this); } //复制、绘画和保存gif private void createGif(){ ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); AnimatedGifEncoder animatedGifEncoder = new AnimatedGifEncoder(); animatedGifEncoder.start(outputStream); animatedGifEncoder.setRepeat(0); animatedGifEncoder.setDelay(0); for (GifHelper.GifFrame frame:frames){ Bitmap bitmap = frame.image; Bitmap copybitmap = bitmap.copy(Bitmap.Config.RGB_565,true); Canvas canvas = new Canvas(copybitmap); Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setTextSize(20); paint.setStyle(Paint.Style.FILL); paint.setTypeface(Typeface.DEFAULT_BOLD); Rect rect = new Rect(); String content = TextUtils.isEmpty(input.getText().toString())?"动次大次":input.getText().toString(); paint.getTextBounds(content,0,content.length(),rect); canvas.drawText(content,copybitmap.getWidth()/2-rect.width()/2,copybitmap.getHeight()*0.2f,paint); animatedGifEncoder.addFrame(copybitmap); animatedGifEncoder.setDelay(frame.delay); } animatedGifEncoder.finish(); try { FileOutputStream fos = new FileOutputStream(dest); outputStream.writeTo(fos); outputStream.flush(); fos.flush(); outputStream.close(); fos.close(); copyFrames = GifHelper.getGif(new FileInputStream(dest)); } catch (IOException e) { e.printStackTrace(); } runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(MainActivity.this,"Gif已经生成。保存路径:\n" + dest.getAbsolutePath(),Toast.LENGTH_LONG).show(); } }); } @Override public void onClick(View v) { if (v.getId() == select.getId()){ Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(intent,SELECT_IMAGE); }else if (v.getId() == save.getId()){ new Thread(){ @Override public void run() { createGif(); } }.start(); } } //将 gif 加载进来 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == SELECT_IMAGE && resultCode == Activity.RESULT_OK && data != null){ Uri selectedImage = data.getData(); String[] filePathColumns = {MediaStore.Images.Media.DATA}; Cursor c = getContentResolver().query(selectedImage, filePathColumns, null, null, null); c.moveToFirst(); int columnIndex = c.getColumnIndex(filePathColumns[0]); imagePath = c.getString(columnIndex); showImage(imagePath); try { frames = GifHelper.getGif(new FileInputStream(imagePath)); } catch (FileNotFoundException e) { e.printStackTrace(); } c.close(); } } private void showImage(String imagePath){ Bitmap bm = BitmapFactory.decodeFile(imagePath); gif_loc.setImageBitmap(bm); } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { new Thread(){ @Override public void run() { createGif(); handler.sendEmptyMessage(MAKEGIFANDPLAY); } }.start(); } class playThread extends Thread{ GifHelper.GifFrame[] frames; int frameLength = 0; int i = 0; public playThread(GifHelper.GifFrame[] frames) { this.frames = frames; frameLength = frames.length; } @Override public void run() { if (frames == null || frames.length == 0) return; if (!frames[i].image.isRecycled()){ Bitmap copy = frames[i].image.copy(Bitmap.Config.RGB_565,true); Message msg = new Message(); msg.obj = copy; msg.what = PLAY; msg.arg1 = frames[i++].delay; handler.sendMessage(msg); } i%=frameLength; } } }