android涂鸦程序(在图像上绘制)

android多媒体图片mediaStore

界面首先由一个choosePicture的按钮,用来从MediaStore取得图片,取得之后,可以在图片上进行绘画,再点击savebutton就可以保存图片到MediaStore。

界面xml文件:

[html] view plaincopyprint?

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

  2. android:layout_width="match_parent"

  3. android:layout_height="match_parent"

  4. android:orientation="vertical" >

  5.  

  6. <Button

  7. android:id="@+id/chooseButton"

  8. android:layout_width="fill_parent"

  9. android:layout_height="wrap_content"

  10. android:gravity="center_horizontal"

  11. android:text="@string/choose" />

  12.  

  13. <ImageView

  14. android:id="@+id/imageView"

  15. android:layout_width="wrap_content"

  16. android:layout_height="wrap_content"

  17. android:layout_gravity="center_horizontal|center_vertical|center"

  18. android:contentDescription="@string/contentDes" />

  19.  

  20. <Button

  21. android:id="@+id/saveButton"

  22. android:layout_width="wrap_content"

  23. android:layout_height="wrap_content"

  24. android:gravity="center_horizontal"

  25. android:layout_gravity="right|bottom"

  26. android:text="@string/save" />

  27.  

  28. </LinearLayout>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/chooseButton"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:text="@string/choose" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal|center_vertical|center"
        android:contentDescription="@string/contentDes" />

    <Button
        android:id="@+id/saveButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:layout_gravity="right|bottom"
        android:text="@string/save" />

</LinearLayout>

string.xml文件定义使用的一些字符串:

[html] view plaincopyprint?

  1. <?xml version="1.0" encoding="utf-8"?>

  2. <resources>

  3.  

  4. <string name="app_name">Scrawl</string>

  5. <string name="action_settings">Settings</string>

  6. <string name="hello_world">Hello world!</string>

  7. <string name="choose">选择图片</string>

  8. <string name="contentDes">图片描述</string>

  9. <string name="save">保存图片</string>

  10. <string name="pleaseChooseImage">请选择图片</string>

  11. <string name="saveSuccess">保存图片成功</string>

  12.  

  13. </resources>

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">Scrawl</string>
    <string name="action_settings">Settings</string>
    <string name="hello_world">Hello world!</string>
    <string name="choose">选择图片</string>
    <string name="contentDes">图片描述</string>
    <string name="save">保存图片</string>
    <string name="pleaseChooseImage">请选择图片</string>
    <string name="saveSuccess">保存图片成功</string>

</resources>

在dimens.xml中定义了margin的top和bottom值为16dp:

[html] view plaincopyprint?

  1. <resources>

  2.  

  3. <!-- Default screen margins, per the Android Design guidelines. -->

  4. <dimen name="activity_horizontal_margin">16dp</dimen>

  5. <dimen name="activity_vertical_margin">16dp</dimen>

  6.  

  7. </resources>

<resources>

    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>

</resources>

主程序:

[java] view plaincopyprint?

  1. package cn.yh.scrawl;

  2.  

  3. import java.io.FileNotFoundException;

  4. import java.io.OutputStream;

  5.  

  6. import android.app.Activity;

  7. import android.content.ContentValues;

  8. import android.content.Intent;

  9. import android.graphics.Bitmap;

  10. import android.graphics.Bitmap.CompressFormat;

  11. import android.graphics.BitmapFactory;

  12. import android.graphics.BitmapFactory.Options;

  13. import android.graphics.Canvas;

  14. import android.graphics.Color;

  15. import android.graphics.Matrix;

  16. import android.graphics.Paint;

  17. import android.net.Uri;

  18. import android.os.Bundle;

  19. import android.provider.MediaStore.Images.Media;

  20. import android.util.Log;

  21. import android.view.Display;

  22. import android.view.Menu;

  23. import android.view.MotionEvent;

  24. import android.view.View;

  25. import android.view.View.OnClickListener;

  26. import android.view.View.OnTouchListener;

  27. import android.view.Window;

  28. import android.widget.Button;

  29. import android.widget.ImageView;

  30. import android.widget.Toast;

  31.  

  32. public class MainActivity extends Activity implements OnClickListener,

  33. OnTouchListener {

  34.  

  35. private static final int CHOOSEPICTURE_REQUESTCODE = 0;

  36. private static final String TAG = "Scrawl";

  37. // �@示�D片的�M件。

  38. private ImageView imageView;

  39. // �x��D片的按�o,和保存�D片的按�o。

  40. private Button chooseButton, saveButton;

  41. // 定�x���位�D�ο螅�第一��包含了�x�穸�D片的�s放版本,第二��是可�的版本,

  42. // �⒌谝��位�D�ο罄L�u到第二��位�D�ο笾校�再在其上方�L�u(�T�f)

  43. private Bitmap bitmap, alteredBitmap;

  44. // 定�x��布

  45. private Canvas canvas;

  46. // 定�x���P

  47. private Paint paint;

  48. // 定�x�入矩�,��使之在一幅�D像上��用空�g�D�Q(比如旋�D,�u�h,�s放,裁剪等)

  49. private Matrix matrix;

  50. // 定�x按下和停止的位置(x,y)座��

  51. private float downX = 0, downY = 0, upX = 0, upY = 0;

  52.  

  53. @Override

  54. protected void onCreate(Bundle savedInstanceState) {

  55. super.onCreate(savedInstanceState);

  56. // �O置主��面

  57. setContentView(R.layout.activity_main);

  58. // �@取��面xml文件相�P的View�ο�

  59. imageView = (ImageView) findViewById(R.id.imageView);

  60. chooseButton = (Button) findViewById(R.id.chooseButton);

  61. saveButton = (Button) findViewById(R.id.saveButton);

  62. // �o���Button�O置onClick�O�事件,�����F了android.view.View.OnClickListener接口

  63. chooseButton.setOnClickListener(this);

  64. saveButton.setOnClickListener(this);

  65. // �oImageView�ο笤O置onTouch�O�,�����F了android.view.View.OnTouchListener接口

  66. imageView.setOnTouchListener(this);

  67. // ��_始,�O置saveButton�椴豢捎��B

  68. saveButton.setEnabled(false);

  69. }

  70.  

  71. @Override

  72. public boolean onCreateOptionsMenu(Menu menu) {

  73. // Inflate the menu; this adds items to the action bar if it is present.

  74. getMenuInflater().inflate(R.menu.main, menu);

  75. return true;

  76. }

  77.  

  78. @Override

  79. public void onClick(View v) {

  80. // TODO Auto-generated method stub

  81. // 因�榻o不同的Button�ο蠖荚O置了onClick�O�,所以需要判�嘤|�l的是哪��Button的�O�事件

  82. switch (v.getId()) {

  83. case R.id.chooseButton:

  84. // 再一次选择图片,�O置saveButton�椴豢捎��B

  85. if (saveButton.isEnabled())

  86. saveButton.setEnabled(false);

  87. // 使用Intent打�_Gallery�x��D片

  88. Intent choosePictureIntent = new Intent(

  89. Intent.ACTION_PICK,

  90. android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

  91. // ��釉�activity,并在�activity�Y束返回���,所以�{用startActivityForResult()方法

  92. startActivityForResult(choosePictureIntent,

  93. CHOOSEPICTURE_REQUESTCODE);

  94. break;

  95. case R.id.saveButton:

  96. if (alteredBitmap != null) {

  97. Uri imageFileUri = getContentResolver().insert(

  98. Media.EXTERNAL_CONTENT_URI, new ContentValues());

  99. try {

  100. OutputStream imageFileOS = getContentResolver()

  101. .openOutputStream(imageFileUri);

  102. //compress方法,压缩成jpg格式,0-100代表了压缩质量 100质量最好 第三个参数把压缩图片写到输出流

  103. alteredBitmap

  104. .compress(CompressFormat.JPEG, 90, imageFileOS);

  105. //保存成功,进行提示

  106. Toast.makeText(this, R.string.saveSuccess,

  107. Toast.LENGTH_LONG).show();

  108. } catch (FileNotFoundException e) {

  109. // TODO Auto-generated catch block

  110. e.printStackTrace();

  111. }

  112. } else {

  113. Toast.makeText(this, R.string.pleaseChooseImage,

  114. Toast.LENGTH_LONG).show();

  115. }

  116. break;

  117. }

  118. }

  119.  

  120. @Override

  121. protected void onActivityResult(int requestCode, int resultCode, Intent data) {

  122. // TODO Auto-generated method stub

  123. super.onActivityResult(requestCode, resultCode, data);

  124. // 判�喾祷厥欠�OK

  125. if (resultCode == RESULT_OK) {

  126. // �@取返回的Uri

  127. Uri imageFileUri = data.getData();

  128. // �@取默�JDisplay,用以得到��前的��和高

  129. Display currentDisplay = getWindowManager().getDefaultDisplay();

  130. int dw = currentDisplay.getWidth();

  131. Log.i(TAG, currentDisplay.getHeight()+"");

  132. Log.i(TAG, chooseButton.getHeight()+"chooseButton");

  133. Log.i(TAG, saveButton.getHeight()+"saveButton");

  134. Log.i(TAG, imageView.getHeight()+"imageView");

  135. Log.i(TAG, getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop()+"ID_ANDROID_CONTENT");

  136. //432 = 48+48+40+16*2+264 默认界面的margin top bottom有16dp title和状态栏40dp 48+48 两个button高度

  137. int dh = currentDisplay.getHeight() - (48+48+40+16*2);

  138. // chooseButton.getHeight()

  139. // - saveButton.getHeight();

  140. // 使用BitmapFactory��建位�DOptions

  141. BitmapFactory.Options bmFactoryOptions = new Options();

  142. // �O置只是�@取�D片的尺寸,�K不是真正的解�a�D片

  143. bmFactoryOptions.inJustDecodeBounds = true;

  144. // 使用decode*方法��建位�D,getContentResolver()�@取�热萏峁┢�

  145. try {

  146. bitmap = BitmapFactory.decodeStream(getContentResolver()

  147. .openInputStream(imageFileUri), null, bmFactoryOptions);

  148. } catch (FileNotFoundException e) {

  149. // TODO Auto-generated catch block

  150. e.printStackTrace();

  151. }

  152. // �算�D像��高�c��前��高的比率

  153. int hRatio = (int) Math.ceil(bmFactoryOptions.outHeight

  154. / (float) dh);

  155. int wRatio = (int) Math

  156. .ceil(bmFactoryOptions.outWidth / (float) dw);

  157. // 判断是按高比率缩放还是宽比例缩放

  158. if (hRatio > 1 || wRatio > 1) {

  159. if (hRatio > wRatio) {

  160. bmFactoryOptions.inSampleSize = hRatio;

  161. } else {

  162. bmFactoryOptions.inSampleSize = wRatio;

  163. }

  164. }

  165. Log.i(TAG, bmFactoryOptions.outHeight/hRatio+"imageView");

  166. // 对图像进行真正的解码

  167. bmFactoryOptions.inJustDecodeBounds = false;

  168. try {

  169. bitmap = BitmapFactory.decodeStream(getContentResolver()

  170. .openInputStream(imageFileUri), null, bmFactoryOptions);

  171. } catch (FileNotFoundException e) {

  172. // TODO Auto-generated catch block

  173. e.printStackTrace();

  174. }

  175. // 在加�d位�D之後,��建一��可�的位�D�ο�alteredBitmap,�K在其中�L�ubitmap�ο�

  176. alteredBitmap = Bitmap.createBitmap(bitmap.getWidth(),

  177. bitmap.getHeight(), bitmap.getConfig());

  178. // 使用alteredBitmap作���造��担���建canvas

  179. canvas = new Canvas(alteredBitmap);

  180. // ��建���P

  181. paint = new Paint();

  182. // �O置���P�色��Color.WHITE

  183. paint.setColor(Color.WHITE);

  184. // �O置���P大小

  185. paint.setStrokeWidth(5);

  186. // ��建matrix,此���D像不�M行任何的�s放,旋�D等操作

  187. matrix = new Matrix();

  188. // �L�ubitmap

  189. canvas.drawBitmap(bitmap, matrix, paint);

  190. // 把alteredBitmap�O置到imageview上面

  191. imageView.setImageBitmap(alteredBitmap);

  192. // 此�r�O置saveButton�榭捎��B

  193. saveButton.setEnabled(true);

  194. imageView.setOnClickListener(this);

  195. }

  196. }

  197.  

  198. @Override

  199. public boolean onTouch(View v, MotionEvent event) {

  200. // TODO Auto-generated method stub

  201. int action = event.getAction();

  202. // 判�嗖煌���B

  203. switch (action) {

  204. case MotionEvent.ACTION_DOWN:

  205. // 按下�r��座��

  206. downX = event.getX();

  207. downY = event.getY();

  208. break;

  209. case MotionEvent.ACTION_MOVE:

  210. // 移�舆^程中,不�嗬L�uLine

  211. upX = event.getX();

  212. upY = event.getY();

  213. canvas.drawLine(downX, downY, upX, upY, paint);

  214. imageView.invalidate();

  215. downX = upX;

  216. downY = upY;

  217. break;

  218. case MotionEvent.ACTION_UP:

  219. // 停止�r,��座��

  220. upX = event.getX();

  221. upY = event.getY();

  222. canvas.drawLine(downX, downY, upX, upY, paint);

  223. imageView.invalidate();

  224. break;

  225. case MotionEvent.ACTION_CANCEL:

  226. break;

  227. default:

  228. break;

  229. }

  230. //返回true表示,一旦事件开始就要继续接受触摸事件

  231. return true;

  232. }

  233.  

  234. }

 

转载网址:http://blog.csdn.net/yhcelebrite/article/details/11786853

你可能感兴趣的:(android,图片,程序,多媒体,涂鸦)