1

我通过json获取php文件中的图片编码数据。我的要求是将图像存储在服务器中的一个文件夹中,前提是应为每个图像分配一个唯一的名称。我对如何将图像存储在具有唯一名称的文件夹中然后再次将图像的路径存储在数据库中产生了很多疑问。我看过几个 StackOverflow 问题和在线资源,但无法清楚地了解它们。对于从事 PHP 工作的人来说,这个问题似乎很简单。但是作为 php 的新手和 Android 开发人员,我无法理解那些不太详细的答案。因此,如果有人可以帮助我提供代码片段和解释,我将不胜感激。我试图用尽可能清晰的注释来解释问题和代码。如果有任何错误,请轻描淡写。以下是我尝试并在某些点卡住的代码。提前致谢..

    <?php
    $response = array();

    // check for required fields
    if (isset($_POST['mailid']) && isset($_POST['category']) && isset($_POST['description']) && isset($_POST['contactNum']) && isset($_POST['lookingto']) && isset($_POST['image'])) {

        $usermail = $_POST['mailid'];
        $category = $_POST['category'];
        $description = $_POST['description'];
        $contactNum = $_POST['contactNum'];
        $lookingto = $_POST['lookingto'];
        $base=$_POST['image'];

        $binary=base64_decode($base);

        $folder = "images/"; // This is my folder "images" in which pics have to be stored.

        $file = fopen('storepic.jpg', 'wb');  // Here I have to give name dynamically to each pic provided that should be unique. Here I mentioned pic name as storepic.jpg, a static name.

        fwrite($file, $binary);

        fclose($file);

        // include db connect class
        require_once __DIR__ . '/db_connect.php';

        // connecting to db
        $db = new DB_CONNECT();

        // mysql inserting a new row
        $result = mysql_query("INSERT INTO details(usermail, category, description, contactnumber,posting_for) VALUES('$usermail', '$category', '$description','$contactNum','$lookingto')");

//// Even after giving dynamic name how can we store the path of the dynamic named image into database in the above query. For that what should be done here..

        // check if row inserted or not
        if ($result) {
            // successfully inserted into database
            $response["success"] = 1;

            // echoing JSON response
            echo json_encode($response);
        } else {
            // failed to insert row
            $response["success"] = 0;


            // echoing JSON response
            echo json_encode($response);
        }
    } else {

        $response["success"] = 0;


        // echoing JSON response
        echo json_encode($response);
    }
    ?>

即使在其他 php 文件中,我也通过选择查询检索数据。我能够获得我插入的正常数据,可以在 Android 客户端应用程序上获得它。但话又说回来如何从路径中获取图像,以便稍后转换为 base64 编码数据,然后作为 json 响应回显..

注意:-我的 UI 不是表单。这是安卓用户界面。。

4

2 回答 2

2
    // A very basic field validation. You should really use mysqli* or PDO*.

    $fields = array(
        'usermail'    => 'mailid',
        'category'    => 'category',
        'description' => 'description',
        'contactNum'  => 'contactNum',
        'lookingto'   => 'lookingto',
        'binary'      => 'base',
    );
    $okay = true;
    foreach($fields as $var => $field)
    {
         if (!isset($_POST[$field]))
             $okay = false;
         if ('binary' == $var)
             ${$var} = base64_decode($_POST[$field]);
         else
             ${$var} = mysql_real_escape_string($_POST[$field]);
    }
    if (!$okay)
    {    
        $response["success"] = 0;
        Header("Content-Type: application/json;charset=UTF-8");
        die(json_encode($response));
    }

    $folder = "images/"; // This is my folder "images" in which pics have to be stored.

    $file   = tempnam($folder, 'image');

    $fp     = fopen($file, 'w');
    fwrite($file, $binary);    
    fclose($file);

    /* BUT WHAT IF THE FILE IS NOT JPEG?
       Then you use GD library and do:

       $gd = ImageCreateFromString($binary);
       if (!$gd)
       {
           // Abort. Image was invalid.
       }
       // Here you can even resize it.
       ImageJPEG($gd, $file, 75); // Quality 75%; useable values from 40 to 100
       ImageDestroy($gd);
    */

    ...

    $result = mysql_query("INSERT INTO details(usermail, category, description, contactnumber,posting_for) VALUES('$usermail', '$category', '$description','$contactNum','$lookingto')");

    // I assume that the above table has an unique ID. So we retrieve it
    $lastid = mysql_insert_id(); 

    rename($file, $newfile = sprintf("%s/img%08d.jpg", $folder, $lastid));

上面,文件名不需要列名,因为名称与行 ID 相同:如果 ID 为 1234,则图像为images/img00001234.jpg.

否则,您必须发出另一个查询:

    UPDATE details SET filename='$newfile' WHERE id = $lastid;

检索

在所有情况下,您都会收到有关要检索的行的一些信息;至少它的 ID,或者无论如何你可以插入一个WHERE. 例如,如果您收到用户电子邮件(并且它是唯一键),您将使用WHERE email='...'.

因此,您将能够发出 aSELECT * FROM details WHERE...并且在这些详细信息中您将找到 ID 或filename字段。

在第一种情况下,您有足够的资源来构建文件名,甚至不需要数据库查询,但请记住,任何知道 ID 的人现在都可以访问图像,这可能是无害的,甚至是需要的(例如,用户公共头像图像)但是有时可能不是。

$lastid  = (int)$_REQUEST['id'];
$newfile = sprintf("%s/img%08d.jpg", $folder, $lastid);

请注意,语法与上述相同;演员要记住,这是用户提供的(int)信息,可能包含各种恶意垃圾。

在第二种情况下,您将发出 aWHERE并从检索到的元组中获取 ID 或直接获取文件名字段。

拥有图像路径,您可以将其发送给用户......如果图像在那里。只是检查。

if (!is_readable($newfile))
{
    Header('HTTP/1.0 404 Not Found')
    readfile('/path/to/beautiful/error-page.html');
    die();
}
// if you are really paranoid, or want to support different quality images,
// you can $gd = imageCreateFromJPEG($newfile); here, check it succeeded or
// send 404 / 500 error if it failed, manipulate $gd and send it along with
// ImageJPEG($gd, '', $quality); instead of the readfile() down there. With
// this approach, you'll better not send Content-Length, though. This makes
// image DOWNLOADS more awkward (you don't see "104K of 1.3M downloaded").

Header('Content-Type: image/jpeg');
Header('Content-Length: ' . filesize($newfile));
readfile($newfile);
die();

……就是这样。在调用上述代码的 HTML 源代码中,您可能有:

<img class="avatar" src="images.php?id=<?php echo $details['id']; ?>" />

(当然,生成 HTML 的 PHP需要访问数据库和 fetch $details)。

还有其他设置允许“调用”PHP 以受保护的方式将数据库元组信息保存在 _GET 参数中,这样即使用户看到图像是通过

image.php?id=1234

并且知道 Bob 的 ID 为 7654,但她仍然无法通过将 1234 更改为 7654 来检索图像,但我不知道这是否有人感兴趣。

使用 Web 浏览器,设置内容就足够了。使用 Internet Explorer,您可能需要文件以 . 结尾.jpg,而这又可能需要使用 URL 重写方案。

于 2012-11-15T17:31:32.230 回答
0
    package com.example.test_image_save;

    import java.io.BufferedInputStream;
    import java.io.FileInputStream;
    import java.io.IOException;

    import android.app.Activity;
    import android.content.ContentValues;
    import android.content.Context;
    import android.content.Intent;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    import android.graphics.BitmapFactory;
    import android.net.Uri;
    import android.os.Bundle;
    import android.os.Environment;
    import android.provider.MediaStore;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.ImageView;
    import android.widget.TextView;
    import android.widget.Toast;

    public class MainActivity extends Activity implements OnClickListener {
    protected static TextView textView;
    protected static ImageView image1, image2;
    protected Button get_image, save_image, read_image;
    private String selectedImagePath;
    private static final int SELECT_PICTURE = 1;
    String DB_NAME = Environment.getExternalStorageDirectory() + "/test.db";
    String TABLE_NAME = "mytable";

    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    image1 = (ImageView) findViewById(R.id.imageView1);
    image2 = (ImageView) findViewById(R.id.imageView2);
    textView = (TextView) findViewById(R.id.textView1);

    get_image = (Button) findViewById(R.id.get_image);
    get_image.setOnClickListener(this);

    save_image = (Button) findViewById(R.id.save_image);
    save_image.setOnClickListener(this);

    read_image = (Button) findViewById(R.id.read_image);
    read_image.setOnClickListener(this);

    }

    public void onClick(View v) {

    int id = v.getId();
    switch (id) {

    case R.id.get_image:
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(
                Intent.createChooser(intent, "Select Picture"),
                SELECT_PICTURE);
        break;

    case R.id.save_image:
        createTable();
        saveInDB();
        break;

    case R.id.read_image:
        readFromDB();
        break;
    default:
        break;

    }
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK) {
        if (requestCode == SELECT_PICTURE) {
            Uri selectedImageUri = data.getData();
            selectedImagePath = getPath(selectedImageUri);
            System.out.println("Image Path : " + selectedImagePath);
            image1.setVisibility(View.VISIBLE);
            image1.setImageURI(selectedImageUri);
        }
    }
    }

    @SuppressWarnings("deprecation")
    public String getPath(Uri uri) {
    String[] projection = { MediaStore.Images.Media.DATA };
    Cursor cursor = managedQuery(uri, projection, null, null, null);
    int column_index = cursor
            .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();
    return cursor.getString(column_index);
    }

    void createTable() {
    SQLiteDatabase myDb = openOrCreateDatabase(DB_NAME,
            Context.MODE_PRIVATE, null);
    String MySQL = "create table if not exists "
            + TABLE_NAME
            + " (_id INTEGER primary key autoincrement, name TEXT not null, image BLOB);";
    myDb.execSQL(MySQL);
    myDb.close();
    }

    void saveInDB() {
    SQLiteDatabase myDb = openOrCreateDatabase(DB_NAME,
            Context.MODE_PRIVATE, null);
    byte[] byteImage1 = null;
    String s = myDb.getPath();

    myDb.execSQL("delete from " + TABLE_NAME);          // clearing the table
    ContentValues newValues = new ContentValues();
    String name = "SachinImages";
    newValues.put("name", name);
    try {
        FileInputStream instream = new FileInputStream(selectedImagePath);
        BufferedInputStream bif = new BufferedInputStream(instream);
        byteImage1 = new byte[bif.available()];
        bif.read(byteImage1);
        newValues.put("image", byteImage1);
        long ret = myDb.insert(TABLE_NAME, null, newValues);
        if (ret < 0)
            textView.append("Error");
    } catch (IOException e) {
        textView.append("Error Exception : " + e.getMessage());
    }
    myDb.close();
    textView.append("\n Saving Details \n Name : " + name);
    textView.append("\n Image Size : " + byteImage1.length + " KB");
    textView.append("\n Saved in DB : " + s + "\n");
    Toast.makeText(this.getBaseContext(),
            "Image Saved in DB successfully.", Toast.LENGTH_SHORT).show();
    }

    void readFromDB() {
    byte[] byteImage2 = null;
    SQLiteDatabase myDb;
    myDb = openOrCreateDatabase(DB_NAME, Context.MODE_PRIVATE, null);
    Cursor cur = myDb.query(TABLE_NAME, null, null, null, null, null, null);
    cur.moveToFirst();
    while (cur.isAfterLast() == false) {
        textView.append("\n Reading Details \n Name : " + cur.getString(1));
        cur.moveToNext();
    }

    // /////Read data from blob field////////////////////
    cur.moveToFirst();
    byteImage2 = cur.getBlob(cur.getColumnIndex("image"));
    setImage(byteImage2);
    cur.close();
    myDb.close();
    Toast.makeText(this.getBaseContext(),
            "Image read from DB successfully.", Toast.LENGTH_SHORT).show();
    Toast.makeText(this.getBaseContext(),
            "If your image is big, please scrolldown to see the result.",
            Toast.LENGTH_SHORT).show();
    }

    void setImage(byte[] byteImage2) {
    image2.setImageBitmap(BitmapFactory.decodeByteArray(byteImage2, 0,
            byteImage2.length));
    textView.append("\n Image Size : " + byteImage2.length + " KB");
    }

    }
于 2015-04-27T05:11:42.503 回答