上传头像

//主代码。支持图片裁剪。调用照相机,相册。

package com.bawei.uploadpicdemo;

import java.io.File;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends Activity {

    protected static final int CHOOSE_PICTURE = 0;
    protected static final int TAKE_PICTURE = 1;
    private static final int CROP_SMALL_PICTURE = 2;
    private static final int REQUESTCODE_PICK =1 ;
    protected static Uri tempUri;
    private ImageView iv_personal_icon;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btn_change = (Button) findViewById(R.id.btn_change);
        iv_personal_icon = (ImageView) findViewById(R.id.iv_personal_icon);
        btn_change.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                showChoosePicDialog();
            }
        });
    }

    /**
     * 显示修改头像的对话框
     */
    protected void showChoosePicDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("设置头像");
        String[] items = { "选择本地照片", "拍照" };
        builder.setNegativeButton("取消", null);
        builder.setItems(items, new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                switch (which) {
                    case CHOOSE_PICTURE: // 选择本地照片
                        Intent pickIntent = new Intent(Intent.ACTION_PICK, null);
                        // 如果朋友们要限制上传到服务器的图片类型时可以直接写如:image/jpeg 、 image/png等的类型
                        pickIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
            startActivityForResult(pickIntent, REQUESTCODE_PICK);
                        break;
                    case TAKE_PICTURE: // 拍照
                        Intent openCameraIntent = new Intent(
                                MediaStore.ACTION_IMAGE_CAPTURE);
                        tempUri = Uri.fromFile(new File(Environment
                                .getExternalStorageDirectory(), "image.jpg"));
                        // 指定照片保存路径(SD卡),image.jpg为一个临时文件,每次拍照后这个图片都会被替换
                        openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, tempUri);
                        startActivityForResult(openCameraIntent, TAKE_PICTURE);
                        break;
                }
            }
        });
        builder.create().show();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) { // 如果返回码是可以用的
            switch (requestCode) {
                case TAKE_PICTURE:
                    startPhotoZoom(tempUri); // 开始对图片进行裁剪处理
                    break;
                case CHOOSE_PICTURE:
                    startPhotoZoom(data.getData()); // 开始对图片进行裁剪处理
                    break;
                case CROP_SMALL_PICTURE:
                    if (data != null) {
                        setImageToView(data); // 让刚才选择裁剪得到的图片显示在界面上
                    }
                    break;
            }
        }
    }

    /**
     * 裁剪图片方法实现
     *
     * @param uri
     */
    protected void startPhotoZoom(Uri uri) {
        if (uri == null) {
            Log.i("tag", "The uri is not exist.");
        }
        tempUri = uri;
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, "image/*");
        // 设置裁剪
        intent.putExtra("crop", "true");
        // aspectX aspectY 是宽高的比例
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        // outputX outputY 是裁剪图片宽高
        intent.putExtra("outputX", 150);
        intent.putExtra("outputY", 150);
        intent.putExtra("return-data", true);
        startActivityForResult(intent, CROP_SMALL_PICTURE);
    }

    /**
     * 保存裁剪之后的图片数据
     */
    protected void setImageToView(Intent data) {
        Bundle extras = data.getExtras();
        if (extras != null) {
            Bitmap photo = extras.getParcelable("data");
            photo = Utils.toRoundBitmap(photo, tempUri); // 这个时候的图片已经被处理成圆形的了
            iv_personal_icon.setImageBitmap(photo);
            uploadPic(photo);
        }
    }

    private void uploadPic(Bitmap bitmap) {
        // 上传至服务器
        // ... 可以在这里把Bitmap转换成file,然后得到file的url,做文件上传操作
        // 注意这里得到的图片已经是圆形图片了
        // bitmap是没有做个圆形处理的,但已经被裁剪了

        String imagePath = Utils.savePhoto(bitmap, Environment
                .getExternalStorageDirectory().getAbsolutePath(), String
                .valueOf(System.currentTimeMillis()));
        Log.e("imagePath", imagePath+"");
        if(imagePath != null){
            // 拿着imagePath上传了
            // ...
        }
    }
}


//工具包

package com.bawei.uploadpicdemo;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.net.Uri;

public class Utils {

    /**
     * Save image to the SD card
     *
     * @param photoBitmap
     * @param photoName
     * @param path
     */
    public static String savePhoto(Bitmap photoBitmap, String path,
            String photoName) {
        String localPath = null;
        if (android.os.Environment.getExternalStorageState().equals(
                android.os.Environment.MEDIA_MOUNTED)) {
            File dir = new File(path);
            if (!dir.exists()) {
                dir.mkdirs();
            }

            File photoFile = new File(path, photoName + ".png");
            FileOutputStream fileOutputStream = null;
            try {
                fileOutputStream = new FileOutputStream(photoFile);
                if (photoBitmap != null) {
                    if (photoBitmap.compress(Bitmap.CompressFormat.PNG, 100,
                            fileOutputStream)) {
                        localPath = photoFile.getPath();
                        fileOutputStream.flush();
                    }
                }
            } catch (FileNotFoundException e) {
                photoFile.delete();
                localPath = null;
                e.printStackTrace();
            } catch (IOException e) {
                photoFile.delete();
                localPath = null;
                e.printStackTrace();
            } finally {
                try {
                    if (fileOutputStream != null) {
                        fileOutputStream.close();
                        fileOutputStream = null;
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return localPath;
    }
    public static Bitmap toRoundBitmap(Bitmap bitmap, Uri tempUri) {
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        float roundPx;
        float left, top, right, bottom, dst_left, dst_top, dst_right, dst_bottom;
        if (width <= height) {
            roundPx = width / 2;
            left = 0;
            top = 0;
            right = width;
            bottom = width;
            height = width;
            dst_left = 0;
            dst_top = 0;
            dst_right = width;
            dst_bottom = width;
        } else {
            roundPx = height / 2;
            float clip = (width - height) / 2;
            left = clip;
            right = width - clip;
            top = 0;
            bottom = height;
            width = height;
            dst_left = 0;
            dst_top = 0;
            dst_right = height;
            dst_bottom = height;
        }

        Bitmap output = Bitmap.createBitmap(width, height, Config.ARGB_8888);
        Canvas canvas = new Canvas(output);

        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect src = new Rect((int) left, (int) top, (int) right,
                (int) bottom);
        final Rect dst = new Rect((int) dst_left, (int) dst_top,
                (int) dst_right, (int) dst_bottom);
        final RectF rectF = new RectF(dst);

        paint.setAntiAlias(true);

        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);

        canvas.drawCircle(roundPx, roundPx, roundPx, paint);

        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(bitmap, src, dst, paint);

        return output;
    }
}


<think>嗯,用户问的是在编程或数学中,/256表示十位,%256表示个位的计算方式及其应用场景。首先,我需要确认用户提到的这种计算方式具体是什么意思。通常来说,/和%分别是除法和取模运算,但这里用户说用除以256的结果作为十位,取模256作为个位。这有点奇怪,因为一般来说,比如在十进制中,/10得到十位以上的数,%10得到个位。但这里用户提到的是用256,可能涉及到的是将数值分解为高位和低位两部分,类似于将16位整数分解为两个8位的字节。 接下来,我需要验证这个理解是否正确。假设有一个数值N,N / 256得到的是高8位,N % 256得到的是低8位,这样可以将一个16位的数拆分成两个8位的部分。例如,如果N是1000,那么1000 /256等于3(余232),所以高8位是3,低8位是232,组合起来就是3*256 +232=1000。这种情况下,用户可能将高8位视为“十位”,低8位视为“个位”,不过这里的位是指字节中的位,而不是十进制中的十位和个位。所以用户可能存在术语上的混淆,需要澄清。 然后,应用场景方面,这种分解常用于数据存储或传输,比如将16位颜色值拆分为两个8位字节,或者处理网络协议中的数据包。此外,在嵌入式系统中,处理寄存器时可能需要将数据拆分为高位和低位部分。另外,位运算中的按位与和移位操作也可以达到类似的效果,比如用右移8位代替除以256,用0xFF的按位与代替%256,这可能更高效。 还需要考虑用户可能的背景,可能是刚开始学习编程,对位运算和数值表示不太熟悉,所以需要用简单的例子来说明。比如用具体数值来演示分解过程,以及如何重组。同时,需要指出这种方法的限制,比如只适用于非负整数,且不超过65535的情况。 最后,生成相关问题时要围绕数值分解、位运算的应用、数据存储和传输中的类似处理,以及不同进制下的分解方法,比如十进制中的/10和%10,帮助用户扩展理解。</think>### 对 `/256` 和 `%256` 计算方式的解释 在编程或数学中,表达式 `N/256` 和 `N%256` 通常用于将整数分解为 **高位(高8位)** 和 **低位(低8位)** 两部分,而非字面意义上的“十位”和“个位”。以下是具体分析: --- #### 1. **数学原理** - **`/256`**:表示整数除法,结果为去掉低8位后的剩余部分。 $$ \text{高位} = \left\lfloor \frac{N}{256} \right\rfloor $$ - **`%256`**:表示取模运算,结果为保留低8位的值。 $$ \text{低位} = N \mod 256 $$ 例如,若 $N = 1000$: - 高位:$1000 / 256 = 3$(余232) - 低位:$1000 \% 256 = 232$ - 重组验证:$3 \times 256 + 232 = 1000$。 --- #### 2. **应用场景** ##### (1) **数据存储与传输** - **颜色编码**:将16位RGB颜色值(如 `0x3E8`)拆分为高8位和低8位存储。 - **网络协议**:将大整数分片传输(如IPv4分片标识符)。 - **嵌入式系统**:处理寄存器或硬件接口时,需将数据拆分为字节操作[^2]。 ##### (2) **位运算优化** - 等价于位操作: ```python high = (N >> 8) & 0xFF # 右移8位取高8位 low = N & 0xFF # 掩码取低8位 ``` ##### (3) **数值压缩** - 将两个8位数值组合为一个16位数值: $$ \text{组合值} = (\text{高位} \times 256) + \text{低位} $$ --- #### 3. **限制与注意事项** - **仅适用于非负整数**:若 $N$ 为负数,需先转换为补码形式。 - **范围限制**:高位和低位均需在 $0 \leq x < 256$ 范围内,否则可能溢出。 --- ### 相关问题 1. 如何用位运算实现 `/256` 和 `%256` 的功能? 2. 为什么计算机中常用256作为分界值? 3. 类似方法在十进制中如何应用(例如 `/10` 和 `%10`)? 4. 如何处理负数的分解与重组? [^1]:ShuQiHere】数值的二进制分解与重组逻辑类似浮点数表示中的分段存储思想。 [^2]: 按位操作与数值分片的底层实现密切相关。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值