Javascript 如何将图像文件放入 json 对象中?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34485420/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 16:24:35  来源:igfitidea点击:

How do you put an image file in a json object?

javascriptarraysjsonmongodb

提问by Dyll Bro

I am making a database for video games, each containing elements like name, genre, and and image of the game. Is it possible to put images into a json object for the db? If not is there a way around this?

我正在为视频游戏制作一个数据库,每个数据库都包含游戏的名称、类型和图像等元素。是否可以将图像放入数据库的 json 对象中?如果没有,有没有办法解决这个问题?

采纳答案by void

I can think of doing it in two ways:

我可以想到通过两种方式来做到这一点:

1.

1.

Storing the file in file system in any directory (say dir1) and renaming it which ensures that the name is unique for every file (may be a timestamp) (say xyz123.jpg), and then storing this name in some DataBase. Then while generating the JSON you pull this filename and generate a complete URL (which will be http://example.com/dir1/xyz123.png)and insert it in the JSON.

将文件存储在文件系统中的任何目录(例如dir1)并重命名它以确保名称对于每个文件都是唯一的(可能是时间戳)(例如xyz123.jpg),然后将此名称存储在某个数据库中。然后在生成 JSON 时提取此文件名并生成一个完整的 URL(将是http://example.com/dir1/xyz123.png)并将其插入到 JSON 中。

2.

2.

Base 64 Encoding, It's basically a way of encoding arbitrary binary data in ASCII text. It takes 4 characters per 3 bytes of data, plus potentially a bit of padding at the end. Essentially each 6 bits of the input is encoded in a 64-character alphabet. The "standard" alphabet uses A-Z, a-z, 0-9 and + and /, with = as a padding character. There are URL-safe variants. So this approach will allow you to put your image directly in the MongoDB, while storing it Encode the image and decode while fetching it, it has some of its own drawbacks:

Base 64 编码,它基本上是一种以 ASCII 文本编码任意二进制数据的方法。每 3 个字节的数据需要 4 个字符,最后可能还有一些填充。本质上,输入的每 6 位都以 64 个字符的字母表进行编码。“标准”字母表使用 AZ、az、0-9 和 + 和 /,并使用 = 作为填充字符。有 URL 安全的变体。因此,这种方法将允许您将图像直接放在 MongoDB 中,在存储它的同时对图像进行编码并在获取它时进行解码,它有一些自身的缺点:

  • base64 encoding makes file sizes roughly 33% larger than their original binary representations, which means more data down the wire (this might be exceptionally painful on mobile networks)
  • data URIs aren't supported on IE6 or IE7.
  • base64 encoded data may possibly take longer to process than binary data.
  • base64 编码使文件大小比其原始二进制表示大约大 33%,这意味着更多的数据传输(这在移动网络上可能会特别痛苦)
  • IE6 或 IE7 不支持数据 URI。
  • base64 编码的数据可能比二进制数据需要更长的时间来处理。

Source

来源

Converting Image to DATA URI

将图像转换为 DATA URI

A.) Canvas

A.) 画布

Load the image into an Image-Object, paint it to a canvas and convert the canvas back to a dataURL.

将图像加载到 Image-Object 中,将其绘制到画布上并将画布转换回 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;
}

Usage

用法

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

Supported input formatsimage/png, image/jpeg, image/jpg, image/gif, image/bmp, image/tiff, image/x-icon, image/svg+xml, image/webp, image/xxx

支持的输入格式image/png,image/jpeg,image/jpg,image/gif,image/bmp,image/tiff,image/x-icon,image/svg+xml,image/webp,image/xxx

B.) FileReader

B.) 文件阅读器

Load the image as blob via XMLHttpRequest and use the FileReader API to convert it to a data URL.

通过 XMLHttpRequest 将图像加载为 blob,并使用 FileReader API 将其转换为数据 URL。

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

这种方法

  • lacks in browser support
  • has better compression
  • works for other file types as well.
  • 缺乏浏览器支持
  • 有更好的压缩
  • 也适用于其他文件类型。

Usage

用法

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

Source

来源

回答by lleaff

The JSONformat can contain only those types of value:

JSON格式可以只包含那些类型的数值:

  • string
  • number
  • object
  • array
  • true
  • false
  • null
  • 细绳
  • 数字
  • 目的
  • 大批
  • 真的
  • 错误的
  • 空值

An image is of the type "binary" which is none of those. So you can't directlyinsert an image into JSON. What you can do is convert the image to a textual representation which can then be used as a normal string.

图像属于“二进制”类型,而这些都不是。所以你不能直接将图像插入到 JSON 中。您可以做的是将图像转换为文本表示,然后可以将其用作普通字符串。

The most common way to achieve that is with what's called base64. Basically, instead of encoding it as 1and 0s, it uses a range of 64 characters which makes the textual representation of it more compact. So for example the number '64' in binary is represented as 1000000, while in base64 it's simply one character: =.

实现这一目标的最常见方法是使用所谓的base64。基本上,它不是将其编码为10s,而是使用 64 个字符的范围,这使得它的文本表示更加紧凑。例如,二进制中的数字 '64' 表示为1000000,而在 base64 中它只是一个字符:=

There are many ways to encode your image in base64 depending on if you want to do it in the browseror not.

有很多方法可以使用 base64 对图像进行编码,具体取决于您是否想在浏览器中进行编码。

Note that if you're developing a web application, it will be way more efficient to store images separately in binary form, and store paths to those images in your JSON or elsewhere. That also allows your client's browser to cache the images.

请注意,如果您正在开发 Web 应用程序,以二进制形式单独存储图像并将这些图像的路径存储在 JSON 或其他地方会更有效。这也允许您客户端的浏览器缓存图像。

回答by c-smile

Use data URL scheme: https://en.wikipedia.org/wiki/Data_URI_scheme

使用数据 URL 方案:https: //en.wikipedia.org/wiki/Data_URI_scheme

In this case you use that string directly in html : <img src="data:image/png;base64,iVBOR....">

在这种情况下,您直接在 html 中使用该字符串: <img src="data:image/png;base64,iVBOR....">

回答by Gandalf the White

To upload files directly to Mongo DB you can make use of Grid FS. Although I will suggest you to upload the file anywhere in file system and put the image's url in the JSON object for every entry and then when you call the data for specific object you can call for the image using URL.

要将文件直接上传到 Mongo DB,您可以使用 Grid FS。尽管我会建议您将文件上传到文件系统中的任何位置,并将图像的 url 放在每个条目的 JSON 对象中,然后当您调用特定对象的数据时,您可以使用 URL 调用图像。

Tell me which backend technology are you using? I can give more suggestions based on that.

告诉我您使用的是哪种后端技术?我可以在此基础上提出更多建议。

回答by Gandalf the White

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
}

PHP File

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!";
}

?>