Jak umieścić plik obrazu w obiekcie json?

Robię bazę danych dla gier wideo, z których każda zawiera takie elementy jak nazwa, gatunek i wizerunek gry. Czy możliwe jest umieszczanie obrazów w obiekcie json dla db? Jeśli nie, to czy jest jakiś sposób na obejście tego?

Author: Dyll Bro, 2015-12-27

5 answers

Mogę myśleć o zrobieniu tego na dwa sposoby:

1.

Przechowywanie pliku w systemie plików w dowolnym katalogu (powiedzmy dir1) i zmiana jego nazwy, która zapewnia, że nazwa jest unikalna dla każdego pliku (może być znacznikiem czasu) (powiedzmy xyz123.jpg), a następnie przechowywanie tej nazwy w jakiejś bazie danych. Następnie podczas generowania JSON wyciągasz tę nazwę pliku i generujesz pełny adres URL (który będzie http://example.com/dir1/xyz123.png) i wstawiasz go do JSON.

2.

Kodowanie bazy 64, to w zasadzie sposób kodowania dowolne dane binarne w tekście ASCII. Zajmuje to 4 znaki na 3 bajty danych, Plus potencjalnie trochę wypełnienia na końcu. Zasadniczo każde 6 bitów wejścia jest zakodowane w 64-znakowym alfabecie. Alfabet" standardowy " używa znaków a-z, a-z, 0-9 oraz + I /, Z = jako znak dopełniający. Istnieją warianty bezpieczne dla URL. Tak więc takie podejście pozwoli Ci umieścić swój obraz bezpośrednio w MongoDB, podczas jego przechowywania Zakoduj obraz i dekoduj podczas pobierania, ma on swoje własne wady:

  • kodowanie base64 sprawia, że rozmiary plików są około 33% większe niż oryginalnych reprezentacji binarnych, co oznacza więcej danych w dół przewodu (może to być wyjątkowo bolesne w sieciach komórkowych)
  • dane URI nie są obsługiwane w IE6 lub IE7.
  • zakodowane dane Base64 mogą być przetwarzane dłużej niż dane binarne.

Źródło

Konwersja obrazu na URI danych

A.) Płótno

Załaduj obraz na obraz-obiekt, namaluj go na płótnie i przekonwertuj płótno z powrotem na dataURL.

function convertToDataURLviaCanvas(url, callback, outputFormat){
    var img = new Image();
    img.crossOrigin = 'Anonymous';
    img.onload = function(){
        var canvas = document.createElement('CANVAS');
        var ctx = canvas.getContext('2d');
        var dataURL;
        canvas.height = this.height;
        canvas.width = this.width;
        ctx.drawImage(this, 0, 0);
        dataURL = canvas.toDataURL(outputFormat);
        callback(dataURL);
        canvas = null; 
    };
    img.src = url;
}

użycie

convertToDataURLviaCanvas('http://bit.ly/18g0VNp', function(base64Img){
    // Base64DataURL
});

Obsługiwane formaty wejściowe image/png, image/jpeg, image/jpg, image/gif, image/bmp, image/tiff, image/x-icon, image/svg+xml, image/webp, image/xxx

B.) FileReader

Załaduj obraz jako blob za pomocą XMLHttpRequest i użyj API FileReader, aby przekonwertować go na adres URL danych.

function convertFileToBase64viaFileReader(url, callback){
    var xhr = new XMLHttpRequest();
    xhr.responseType = 'blob';
    xhr.onload = function() {
      var reader  = new FileReader();
      reader.onloadend = function () {
          callback(reader.result);
      }
      reader.readAsDataURL(xhr.response);
    };
    xhr.open('GET', url);
    xhr.send();
}

This approach

  • brak w przeglądarce Wsparcie
  • ma lepszą kompresję
  • działa również dla innych typów plików.

użycie

convertFileToBase64viaFileReader('http://bit.ly/18g0VNp', function(base64Img){
    // Base64DataURL
});

Źródło

 70
Author: void,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

Format JSON może zawierać tylko te typy wartości:

  • string
  • liczba
  • obiekt
  • tablica
  • true
  • false
  • null

Obraz jest typu "binarny", który nie jest żadnym z nich. Więc nie możesz bezpośrednio wstawić obrazu do JSON. To, co możesz zrobić, to przekonwertować obraz na reprezentację tekstową, która może być następnie używana jako zwykły ciąg znaków.

Najbardziej powszechnym sposobem na osiągnięcie tego jest to, co nazywa się base64 . Zasadniczo, zamiast kodowania jako 1 i 0 S, używa zakresu 64 znaków, co sprawia, że tekstowa reprezentacja jest bardziej zwarta. Na przykład liczba' 64 ' w binarnym jest reprezentowana jako 1000000, podczas gdy w base64 jest to po prostu jeden znak: =.

Istnieje wiele sposobów kodowania obrazu w base64 w zależności od tego, czy chcesz to zrobić w przeglądarce, czy nie.

Zauważ, że jeśli jesteś rozwijając aplikację internetową, znacznie wydajniejsze będzie przechowywanie obrazów oddzielnie w postaci binarnej i przechowywanie ścieżek do tych obrazów w JSON lub w innym miejscu. Pozwala to również przeglądarce klienta na buforowanie obrazów.

 31
Author: lleaff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-11-28 11:26:28

Użyj schematu URL danych: https://en.wikipedia.org/wiki/Data_URI_scheme

W tym przypadku używasz tego ciągu bezpośrednio w html: <img src="data:image/png;base64,iVBOR....">

 7
Author: c-smile,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-27 22:23:15

Aby przesłać pliki bezpośrednio do Mongo DB możesz skorzystać z Grid FS. Chociaż sugeruję, aby przesłać plik w dowolnym miejscu w systemie plików i umieścić adres URL obrazu w obiekcie JSON dla każdego wpisu, a następnie podczas wywoływania danych dla konkretnego obiektu można wywołać obraz za pomocą adresu URL.

Powiedz mi jakiej technologii backendu używasz? Na tej podstawie mogę dać więcej sugestii.

 1
Author: Gandalf the White,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-27 22:22:04
public class UploadToServer extends Activity {

TextView messageText;
Button uploadButton;
int serverResponseCode = 0;
ProgressDialog dialog = null;

String upLoadServerUri = null;

/********** File Path *************/
final String uploadFilePath = "/mnt/sdcard/";
final String uploadFileName = "Quotes.jpg";

@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_upload_to_server);

    uploadButton = (Button) findViewById(R.id.uploadButton);
    messageText = (TextView) findViewById(R.id.messageText);

    messageText.setText("Uploading file path :- '/mnt/sdcard/"
            + uploadFileName + "'");

    /************* Php script path ****************/
    upLoadServerUri = "http://192.1.1.11/hhhh/UploadToServer.php";

    uploadButton.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {

            dialog = ProgressDialog.show(UploadToServer.this, "",
                    "Uploading file...", true);

            new Thread(new Runnable() {
                public void run() {
                    runOnUiThread(new Runnable() {
                        public void run() {
                            messageText.setText("uploading started.....");
                        }
                    });

                    uploadFile(uploadFilePath + "" + uploadFileName);

                }
            }).start();
        }
    });
}

public int uploadFile(String sourceFileUri) {

    String fileName = sourceFileUri;

    HttpURLConnection connection = null;
    DataOutputStream dos = null;
    String lineEnd = "\r\n";
    String twoHyphens = "--";
    String boundary = "*****";
    int bytesRead, bytesAvailable, bufferSize;
    byte[] buffer;
    int maxBufferSize = 1 * 1024 * 1024;
    File sourceFile = new File(sourceFileUri);

    if (!sourceFile.isFile()) {

        dialog.dismiss();

        Log.e("uploadFile", "Source File not exist :" + uploadFilePath + ""
                + uploadFileName);

        runOnUiThread(new Runnable() {
            public void run() {
                messageText.setText("Source File not exist :"
                        + uploadFilePath + "" + uploadFileName);
            }
        });

        return 0;

    } else {
        try {

            // open a URL connection to the Servlet
            FileInputStream fileInputStream = new FileInputStream(
                    sourceFile);
            URL url = new URL(upLoadServerUri);

            // Open a HTTP connection to the URL
            connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true); // Allow Inputs
            connection.setDoOutput(true); // Allow Outputs
            connection.setUseCaches(false); // Don't use a Cached Copy
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Connection", "Keep-Alive");
            connection.setRequestProperty("ENCTYPE", "multipart/form-data");
            connection.setRequestProperty("Content-Type",
                    "multipart/form-data;boundary=" + boundary);
            connection.setRequestProperty("uploaded_file", fileName);

            dos = new DataOutputStream(connection.getOutputStream());

            dos.writeBytes(twoHyphens + boundary + lineEnd);
            // dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\""
            // + fileName + "\"" + lineEnd);
            dos.writeBytes("Content-Disposition: post-data; name=uploadedfile;filename="
                    + URLEncoder.encode(fileName, "UTF-8") + lineEnd);

            dos.writeBytes(lineEnd);

            // create a buffer of maximum size
            bytesAvailable = fileInputStream.available();

            bufferSize = Math.min(bytesAvailable, maxBufferSize);
            buffer = new byte[bufferSize];

            // read file and write it into form...
            bytesRead = fileInputStream.read(buffer, 0, bufferSize);

            while (bytesRead > 0) {

                dos.write(buffer, 0, bufferSize);
                bytesAvailable = fileInputStream.available();
                bufferSize = Math.min(bytesAvailable, maxBufferSize);
                bytesRead = fileInputStream.read(buffer, 0, bufferSize);

            }

            // send multipart form data necesssary after file data...
            dos.writeBytes(lineEnd);
            dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

            // Responses from the server (code and message)
            int serverResponseCode = connection.getResponseCode();
            String serverResponseMessage = connection.getResponseMessage();

            Log.i("uploadFile", "HTTP Response is : "
                    + serverResponseMessage + ": " + serverResponseCode);

            if (serverResponseCode == 200) {

                runOnUiThread(new Runnable() {
                    public void run() {

                        String msg = "File Upload Completed.\n\n See uploaded file here : \n\n"
                                + " http://www.androidexample.com/media/uploads/"
                                + uploadFileName;

                        messageText.setText(msg);
                        Toast.makeText(UploadToServer.this,
                                "File Upload Complete.", Toast.LENGTH_SHORT)
                                .show();
                    }
                });
            }

            // close the streams //
            fileInputStream.close();
            dos.flush();
            dos.close();

        } catch (MalformedURLException ex) {

            dialog.dismiss();
            ex.printStackTrace();

            runOnUiThread(new Runnable() {
                public void run() {
                    messageText
                            .setText("MalformedURLException Exception : check script url.");
                    Toast.makeText(UploadToServer.this,
                            "MalformedURLException", Toast.LENGTH_SHORT)
                            .show();
                }
            });

            Log.e("Upload file to server", "error: " + ex.getMessage(), ex);
        } catch (Exception e) {

            dialog.dismiss();
            e.printStackTrace();

            runOnUiThread(new Runnable() {
                public void run() {
                    messageText.setText("Got Exception : see logcat ");
                    Toast.makeText(UploadToServer.this,
                            "Got Exception : see logcat ",
                            Toast.LENGTH_SHORT).show();
                }
            });
            Log.e("Upload file to server Exception",
                    "Exception : " + e.getMessage(), e);
        }
        dialog.dismiss();
        return serverResponseCode;

    } // End else block
}

plik PHP

<?php
$target_path  = "./Upload/";
$target_path = $target_path . basename( $_FILES['uploadedfile']['name']);

if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
    echo "The file ".  basename( $_FILES['uploadedfile']['name']).    " has been uploaded";
} else {
    echo "There was an error uploading the file, please try again!";
}

?>
 -2
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-27 22:22:37