ฉันจะแปลงรูปภาพเป็นสตริง Base64 ได้อย่างไร


143

รหัสในการแปลงรูปภาพ (สูงสุด 200 KB) เป็นสตริง Base64 คืออะไร

ฉันต้องรู้ว่าต้องทำอย่างไรกับ Android เพราะฉันต้องเพิ่มฟังก์ชั่นเพื่ออัปโหลดรูปภาพไปยังเซิร์ฟเวอร์ระยะไกลในแอพหลักของฉันวางลงในแถวของฐานข้อมูลเป็นสตริง

ฉันกำลังค้นหาใน Google และใน Stack Overflow แต่ฉันไม่สามารถหาตัวอย่างง่าย ๆ ที่ฉันสามารถจ่ายได้และฉันยังพบตัวอย่างบางอย่าง แต่พวกเขาไม่ได้พูดถึงการเปลี่ยนเป็นสตริง จากนั้นฉันต้องแปลงเป็นสตริงเพื่ออัปโหลดโดย JSON ไปยังเซิร์ฟเวอร์ระยะไกลของฉัน

คำตอบ:


330

คุณสามารถใช้คลาส Base64 Android:

String encodedImage = Base64.encodeToString(byteArrayImage, Base64.DEFAULT);

คุณจะต้องแปลงภาพของคุณเป็นอาร์เรย์ไบต์ นี่คือตัวอย่าง:

Bitmap bm = BitmapFactory.decodeFile("/path/to/image.jpg");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100, baos); // bm is the bitmap object
byte[] b = baos.toByteArray();

* อัพเดท *

หากคุณกำลังใช้ไลบรารี SDK ที่เก่ากว่า (เพราะคุณต้องการให้มันทำงานบนโทรศัพท์ที่มีระบบปฏิบัติการรุ่นเก่ากว่า) คุณจะไม่ได้บรรจุคลาส Base64 ไว้ (เนื่องจากเพิ่งเปิดตัวในระดับ API 8 AKA เวอร์ชัน 2.2)

ตรวจสอบบทความนี้เพื่อหาวิธีแก้ไข:

วิธีการเข้ารหัส base64 ถอดรหัส Android


ตกลงและพวกเขาฉันสามารถใส่สตริงที่ (encondedImage) ลงในคอลัมน์ฐานข้อมูลระยะไกลด้วย PHP + JSON ???? ประเภทใดที่จะเป็นคอลัมน์ของฐานข้อมูล VARCHAR?
NullPointerException

ด้วย VARCHAR คุณต้องระบุว่ามันใหญ่แค่ไหนดังนั้น TEXT น่าจะดีกว่า รูปภาพอาจมีขนาด
เท่าใดก็ได้

สวัสดีฉันกำลังทดสอบ แต่มันให้ข้อผิดพลาดใน Base64 มันไม่สามารถแยกชั้นเรียนได้ ฉันสร้าง Ctrl + shift + O เพื่อรับการนำเข้า แต่ไม่ได้รับการนำเข้า ... ¿จะแก้ไขได้อย่างไร?
NullPointerException

4
สำหรับฉันทำงานหลังจากแทนที่: String encodedImage = Base64.encode (byteArrayImage, Base64.DEFAULT); โดย: String encodedImage = Base64.encodeToString (byteArrayImage, Base64.DEFAULT);
PakitoV

3
มีใครรู้บ้างไหมว่าวิธีนี้ทำให้การบีบอัดไฟล์ไม่มีความหมาย? ทำไม upvoted นี้ถึงเป็นอย่างนั้น ?? คำตอบของจันทราเซคาร์นั้นมีประสิทธิภาพมากที่สุด
ElYeante

103

แทนการใช้คุณยังสามารถทำเช่นนี้ผ่านจิ๊บจ๊อยBitmap InputStreamฉันไม่แน่ใจ แต่ฉันคิดว่ามันค่อนข้างมีประสิทธิภาพ

InputStream inputStream = new FileInputStream(fileName); // You can get an inputStream using any I/O API
byte[] bytes;
byte[] buffer = new byte[8192];
int bytesRead;
ByteArrayOutputStream output = new ByteArrayOutputStream();

try {
    while ((bytesRead = inputStream.read(buffer)) != -1) {
        output.write(buffer, 0, bytesRead);
    }
}
catch (IOException e) {
    e.printStackTrace();
}

bytes = output.toByteArray();
String encodedString = Base64.encodeToString(bytes, Base64.DEFAULT);

3
แน่นอนว่ามันมีประสิทธิภาพมากกว่า เพียงแปลงไฟล์เป็นการแสดงพื้นฐานของ 64 และหลีกเลี่ยงการบีบอัดภาพที่ไม่มีความหมายอย่างแท้จริง
ElYeante

คือชื่อไฟล์ที่นี่เส้นทางของไฟล์หรือชื่อไฟล์จริง ??? โปรดอย่าลืมติดแท็กฉัน :) ขอบคุณ
Rakeeb Rajbhandari

2
@ user2247689 เมื่อคุณพยายามเข้าถึงไฟล์โดยชัดแจ้งคุณต้องระบุพา ธ ที่สมบูรณ์ของไฟล์รวมถึงชื่อไฟล์ หากไฟล์มีอยู่ในพา ธ เดียวกันกับที่ซอร์สโปรแกรมของคุณแสดงอยู่ชื่อไฟล์ก็เพียงพอแล้ว
จันทราเซคาร์

2
คำถาม '8192' หมายถึงอะไรที่นี่ขนาดไฟล์หรืออะไร
Devesh Khandelwal

1
รหัสนี้ใช้งานไม่ได้ใช้เวลาหลายชั่วโมงในการแก้ไขปัญหา
Ramkesh Yadav

7

หากคุณต้องการ Base64 มากกว่า JSON ให้ตรวจสอบJackson : มันมีการสนับสนุนอย่างชัดเจนสำหรับข้อมูลไบนารีอ่าน / เขียนเป็น Base64 ทั้งในระดับต่ำ (JsonParser, JsonGenerator) และระดับการผูกข้อมูล ดังนั้นคุณสามารถมีPOJO ที่มีคุณสมบัติไบต์ [] และการเข้ารหัส / ถอดรหัสจะได้รับการจัดการโดยอัตโนมัติ

และก็มีประสิทธิภาพด้วยเช่นกัน


1
ยากเกินไปสำหรับฉันทักษะของฉันต่ำมากด้วยสิ่งนี้ฉันตรวจสอบใน google และไม่สามารถหาตัวอย่างง่าย ๆ ... บางทีถ้าคุณสามารถให้รหัสตัวอย่างเช่น xil3 ฉันจะเข้าใจ
NullPointerException

5
// Put the image file path into this method
public static String getFileToByte(String filePath){
    Bitmap bmp = null;
    ByteArrayOutputStream bos = null;
    byte[] bt = null;
    String encodeString = null;
    try{
        bmp = BitmapFactory.decodeFile(filePath);
        bos = new ByteArrayOutputStream();
        bmp.compress(Bitmap.CompressFormat.JPEG, 100, bos);
        bt = bos.toByteArray();
        encodeString = Base64.encodeToString(bt, Base64.DEFAULT);
    }
    catch (Exception e){
      e.printStackTrace();
    }
    return encodeString;
}

3

รหัสนี้ทำงานได้สมบูรณ์แบบในโครงการของฉัน:

profile_image.buildDrawingCache();
Bitmap bmap = profile_image.getDrawingCache();
String encodedImageData = getEncoded64ImageStringFromBitmap(bmap);


public String getEncoded64ImageStringFromBitmap(Bitmap bitmap) {
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    bitmap.compress(CompressFormat.JPEG, 70, stream);
    byte[] byteFormat = stream.toByteArray();

    // Get the Base64 string
    String imgString = Base64.encodeToString(byteFormat, Base64.NO_WRAP);

    return imgString;
}

2

หากคุณกำลังทำสิ่งนี้บนAndroidต่อไปนี้เป็นผู้ช่วยที่คัดลอกมาจากReact Native codebase :

import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import android.util.Base64;
import android.util.Base64OutputStream;
import android.util.Log;

// You probably don't want to do this with large files
// (will allocate a large string and can cause an OOM crash).
private String readFileAsBase64String(String path) {
  try {
    InputStream is = new FileInputStream(path);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    Base64OutputStream b64os = new Base64OutputStream(baos, Base64.DEFAULT);
    byte[] buffer = new byte[8192];
    int bytesRead;
    try {
      while ((bytesRead = is.read(buffer)) > -1) {
        b64os.write(buffer, 0, bytesRead);
      }
      return baos.toString();
    } catch (IOException e) {
      Log.e(TAG, "Cannot read file " + path, e);
      // Or throw if you prefer
      return "";
    } finally {
      closeQuietly(is);
      closeQuietly(b64os); // This also closes baos
    }
  } catch (FileNotFoundException e) {
    Log.e(TAG, "File not found " + path, e);
    // Or throw if you prefer
    return "";
  }
}

private static void closeQuietly(Closeable closeable) {
  try {
    closeable.close();
  } catch (IOException e) {
  }
}

2
(จะจัดสรรสตริงที่มีขนาดใหญ่และอาจทำให้เกิดความผิดพลาดของ OOM) ดังนั้นในกรณีนี้การแก้ปัญหาคืออะไร?
Ibrahim Disouki

1

นี่คือรหัสการเข้ารหัสและการถอดรหัสใน Kotlin:

 fun encode(imageUri: Uri): String {
    val input = activity.getContentResolver().openInputStream(imageUri)
    val image = BitmapFactory.decodeStream(input , null, null)

    // Encode image to base64 string
    val baos = ByteArrayOutputStream()
    image.compress(Bitmap.CompressFormat.JPEG, 100, baos)
    var imageBytes = baos.toByteArray()
    val imageString = Base64.encodeToString(imageBytes, Base64.DEFAULT)
    return imageString
}

fun decode(imageString: String) {

    // Decode base64 string to image
    val imageBytes = Base64.decode(imageString, Base64.DEFAULT)
    val decodedImage = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)

    imageview.setImageBitmap(decodedImage)
}

0
byte[] decodedString = Base64.decode(result.getBytes(), Base64.DEFAULT);

6
ในขณะที่รหัสนี้อาจตอบคำถาม แต่มีบริบทเพิ่มเติมเกี่ยวกับสาเหตุและ / หรือวิธีการที่รหัสนี้ตอบคำถามช่วยปรับปรุงมูลค่าระยะยาว
โดนัลด์ดั๊ก

คำอธิบายจะอยู่ในลำดับ
Peter Mortensen

0

ด้านล่างเป็นรหัสเทียมที่อาจช่วยคุณได้:

public  String getBase64FromFile(String path)
{
    Bitmap bmp = null;
    ByteArrayOutputStream baos = null;
    byte[] baat = null;
    String encodeString = null;
    try
    {
        bmp = BitmapFactory.decodeFile(path);
        baos = new ByteArrayOutputStream();
        bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        baat = baos.toByteArray();
        encodeString = Base64.encodeToString(baat, Base64.DEFAULT);
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }

   return encodeString;
}

0

แปลงภาพเป็นสตริง Base64 ใน Android:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.yourimage);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] imageBytes = baos.toByteArray();
String imageString = Base64.encodeToString(imageBytes, Base64.DEFAULT);

0

นี่คือรหัสสำหรับการเข้ารหัสภาพและการถอดรหัสภาพ

ในไฟล์ XML

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="yyuyuyuuyuyuyu"
    android:id="@+id/tv5"
/>

ในไฟล์ Java:

TextView textView5;
Bitmap bitmap;

textView5 = (TextView) findViewById(R.id.tv5);

bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.logo);

new AsyncTask<Void, Void, String>() {
    @Override
    protected String doInBackground(Void... voids) {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 70, stream);
        byte[] byteFormat = stream.toByteArray();

        // Get the Base64 string
        String imgString = Base64.encodeToString(byteFormat, Base64.NO_WRAP);

        return imgString;
    }

    @Override
    protected void onPostExecute(String s) {
       textView5.setText(s);
    }
}.execute();

สิ่งนี้จะรวบรวมหรือไม่ คุณปล่อยอะไรไปหรือเปล่า?
Peter Mortensen

0

สำหรับผู้ที่มองหาวิธีที่มีประสิทธิภาพในการแปลงไฟล์ภาพเป็นสตริง Base64 โดยไม่ต้องบีบอัดหรือแปลงไฟล์เป็นบิตแมปก่อนคุณสามารถเข้ารหัสไฟล์เป็น base64 แทน

val base64EncodedImage = FileInputStream(imageItem.localSrc).use {inputStream - >
    ByteArrayOutputStream().use {outputStream - >
            Base64OutputStream(outputStream, Base64.DEFAULT).use {
                base64FilterStream - >
                    inputStream.copyTo(base64FilterStream)
                base64FilterStream.flush()
                outputStream.toString()
            }
      }
}

หวังว่านี่จะช่วยได้!


-1

ใช้รหัสนี้:

byte[] decodedString = Base64.decode(Base64String.getBytes(), Base64.DEFAULT);

Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);

นี่เป็นสิ่งที่ตรงกันข้าม
Rafael Ruiz Muñoz
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.