You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:无Picker实现相机拍照压缩并上传至XAMPP服务器

我来帮你梳理下实现这个需求的完整方案,结合你提到的「不能用Picker」「压缩上传到XAMPP」这些要求,咱们一步步拆解来做:

一、先搞定拍照+本地存储的基础流程

首先得把拍照后的图片存到内部存储的photo文件夹,同时把文件名记录到image.json里,这部分是核心基础:

1. 创建内部存储的photo文件夹

// 以Android为例,获取内部存储根目录下的photo文件夹路径
File photoDir = new File(getFilesDir(), "photo");
if (!photoDir.exists()) {
    photoDir.mkdirs(); // 不存在就创建文件夹
}

2. 保存拍照得到的图片

假设你已经通过相机API拿到了拍摄的Bitmap对象:

// 生成唯一文件名(用时间戳避免重复)
String fileName = "IMG_" + System.currentTimeMillis() + ".jpg";
File imageFile = new File(photoDir, fileName);

// 保存原图到photo文件夹
try (FileOutputStream fos = new FileOutputStream(imageFile)) {
    capturedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos); // 100是无损质量
} catch (IOException e) {
    e.printStackTrace();
}

3. 更新image.json记录文件名

要先读取已有的JSON内容,再添加新文件名:

File jsonFile = new File(getFilesDir(), "image.json");
JSONArray imageNames = new JSONArray();

// 如果json文件已存在,先读取现有内容
if (jsonFile.exists()) {
    String jsonContent = new String(Files.readAllBytes(jsonFile.toPath()));
    imageNames = new JSONArray(jsonContent);
}

// 添加新文件名并写回文件
imageNames.put(fileName);
try (FileWriter writer = new FileWriter(jsonFile)) {
    writer.write(imageNames.toString());
} catch (IOException e) {
    e.printStackTrace();
}
二、图片压缩(完全不用Picker)

这里给你两种实用的压缩方式,按需选择:

1. 质量压缩(只改文件大小,分辨率不变)

适合想要保留原图尺寸,但减少文件体积的场景:

public File compressImageQuality(File originalFile, int quality) {
    try {
        Bitmap bitmap = BitmapFactory.decodeFile(originalFile.getAbsolutePath());
        // 生成压缩后的文件(前缀加COMPRESSED区分原图)
        File compressedFile = new File(originalFile.getParent(), "COMPRESSED_" + originalFile.getName());
        
        try (FileOutputStream fos = new FileOutputStream(compressedFile)) {
            // quality范围0-100,数值越小压缩率越高、画质越差
            bitmap.compress(Bitmap.CompressFormat.JPEG, quality, fos);
        }
        bitmap.recycle(); // 及时释放内存
        return compressedFile;
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
}

调用示例:File compressedFile = compressImageQuality(imageFile, 50);(50%质量压缩)

2. 尺寸压缩(缩小分辨率,大幅减体积)

适合对图片尺寸要求不高的场景:

public File compressImageSize(File originalFile, float maxWidth, float maxHeight) {
    try {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true; // 先只读取图片尺寸,不加载到内存
        BitmapFactory.decodeFile(originalFile.getAbsolutePath(), options);
        
        // 计算缩放比例
        int width = options.outWidth;
        int height = options.outHeight;
        int inSampleSize = 1;
        if (height > maxHeight || width > maxWidth) {
            final int halfHeight = height / 2;
            final int halfWidth = width / 2;
            while ((halfHeight / inSampleSize) >= maxHeight && (halfWidth / inSampleSize) >= maxWidth) {
                inSampleSize *= 2;
            }
        }
        
        options.inJustDecodeBounds = false;
        options.inSampleSize = inSampleSize;
        Bitmap bitmap = BitmapFactory.decodeFile(originalFile.getAbsolutePath(), options);
        
        File compressedFile = new File(originalFile.getParent(), "COMPRESSED_" + originalFile.getName());
        try (FileOutputStream fos = new FileOutputStream(compressedFile)) {
            bitmap.compress(Bitmap.CompressFormat.JPEG, 80, fos);
        }
        bitmap.recycle();
        return compressedFile;
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
}

调用示例:File compressedFile = compressImageSize(imageFile, 1080f, 1920f);(缩到最大1080*1920)

三、上传到XAMPP服务器

这部分需要服务器端和客户端配合:

1. XAMPP服务器端接收脚本

在XAMPP的htdocs目录下创建upload.php文件,用来接收上传的图片:

<?php
$targetDir = "uploads/";
// 自动创建uploads文件夹
if (!file_exists($targetDir)) {
    mkdir($targetDir, 0777, true);
}

$targetFile = $targetDir . basename($_FILES["image"]["name"]);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($targetFile,PATHINFO_EXTENSION));

// 验证是否为真实图片
if(isset($_POST["submit"])) {
    $check = getimagesize($_FILES["image"]["tmp_name"]);
    if($check !== false) {
        $uploadOk = 1;
    } else {
        echo "文件不是图片格式";
        $uploadOk = 0;
    }
}

// 检查文件大小(限制为5MB)
if ($_FILES["image"]["size"] > 5000000) {
    echo "文件过大,最大支持5MB";
    $uploadOk = 0;
}

// 允许的图片格式
if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg") {
    echo "仅支持JPG/PNG/JPEG格式";
    $uploadOk = 0;
}

// 执行上传
if ($uploadOk == 0) {
    echo "上传失败";
} else {
    if (move_uploaded_file($_FILES["image"]["tmp_name"], $targetFile)) {
        echo "文件上传成功:". basename( $_FILES["image"]["name"]);
    } else {
        echo "上传过程出错";
    }
}
?>

2. 客户端上传代码(以Android为例,用OkHttp)

先在项目依赖里添加OkHttp:

implementation 'com.squareup.okhttp3:okhttp:4.9.3'

然后写上传逻辑:

public void uploadImageToServer(File imageFile) {
    OkHttpClient client = new OkHttpClient();
    
    // 构建表单请求体,把图片作为文件参数上传
    RequestBody requestBody = new MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            .addFormDataPart("image", imageFile.getName(),
                    RequestBody.create(MediaType.parse("image/jpeg"), imageFile))
            .addFormDataPart("submit", "upload") // 对应PHP里的$_POST["submit"]
            .build();
    
    // 替换成你的XAMPP服务器IP(比如本地局域网IP是192.168.1.100)
    Request request = new Request.Builder()
            .url("http://192.168.1.100/upload.php")
            .post(requestBody)
            .build();
    
    // 异步上传,避免阻塞主线程
    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            e.printStackTrace();
            // 处理上传失败逻辑,比如提示用户
        }
        
        @Override
        public void onResponse(Call call, Response response) throws IOException {
            if (response.isSuccessful()) {
                String result = response.body().string();
                // 上传成功后可以选择删除本地压缩文件,或者做其他逻辑
            } else {
                // 处理响应失败逻辑
            }
        }
    });
}

注意:要确保客户端和XAMPP服务器在同一局域网,Android端还要添加INTERNET权限,Android 9及以上需要在AndroidManifest.xml的<application>标签里加android:usesCleartextTraffic="true"允许明文HTTP请求。

四、完整流程串联
  1. 通过相机API拍摄图片得到Bitmap
  2. 保存原图到内部存储的photo文件夹
  3. 更新image.json记录新文件名
  4. 调用压缩方法生成压缩后的图片文件
  5. 调用上传方法把压缩文件传到XAMPP服务器
  6. 可选:上传成功后删除本地压缩文件,释放存储空间

内容的提问来源于stack exchange,提问作者Manu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:51:28