0

Android クライアントがあり、Android からサーバーに画像を送信したい。画像をバイト配列に変換してから、バイト配列を base64 に変換し、base64 文字列をサーバーに送信し、サーバーでデコードしてから保存します。私のSQLサーバー2008 r2で。

私の問題

文字列をデータベースに保存して正しく取得することはできません。例外は発生せず、結果は得られますが、間違った結果のようです。

私はこれを行うことによってそれを結論付けます。

1-アンドロイドからサーバーにbase64を送信し、取得した文字列を静的変数に保存しました。2-サーバーに静的文字列を取得するように依頼したところ、Android に画像が返されました。3-しかし、データベースに保存したはずの画像をサーバーに取得するように依頼したところ、間違った画像になりました。実際には結果が得られますが、この結果は再度デコードできません。

データベースに画像を挿入して取得するためのコードを説明します。何が間違っているのか教えてください。

データベースに保存

void uploadImage(String image) {
Connection con = Database.getConnection();
        CallableStatement callableStatement = null;
        try {
            callableStatement = con
                    .prepareCall("{call insertRestaurantFoodImage(?,?)}");
            ByteArrayInputStream b = new ByteArrayInputStream(
                    stringImage.getBytes());
            callableStatement.setInt(1, ID);
            ;
            callableStatement.setBinaryStream(2, b,
                    stringImage.getBytes().length);
            callableStatement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
}

画像を挿入するストアドプロシージャは

ALTER PROCEDURE dbo.insertRestaurantFoodImage
    (
    @restaurantFoodID INT,
    @image VARBINARY(MAX)
    )
AS
BEGIN
    SET NOCOUNT ON
    UPDATE Food_Restaurant
    SET [image] = @image
    WHERE ID = @restaurantFoodID
END

データベースから取得

Connection con = Database.getConnection();
            CallableStatement callableStatement = null;
            try {
                callableStatement = con
                        .prepareCall("{call getRestaurantFoodImage(?,?)}");
                callableStatement.setInt(1, getID());
                callableStatement.registerOutParameter(2,
                        java.sql.Types.VARBINARY);
                callableStatement.execute();
                byte[] bytes = callableStatement.getBytes(2);
                image = new String(bytes);
            } catch (SQLException e) {
                e.printStackTrace();
            }

データベースから取得するストアド プロシージャは次のとおりです。

ALTER PROCEDURE dbo.getRestaurantFoodImage
(
    @foodRestaurantID INT,
    @image VARBINARY(MAX) OUTPUT
    )
AS
BEGIN
    SET NOCOUNT ON
    SELECT @image = [image]
    FROM Food_Restaurant
    WHERE ID = @foodRestaurantID
END

話しすぎたのかもしれませんが、前の質問で、ユーザーは、コードを入れるだけでなく、問題と私がしていることを入れなければならないと言いました。

アンドロイドでエンコードとデコードする方法について私に尋ねたユーザーのために、ここにそれがあります:

エンコード

private byte[] getBytesFromBitmap(Bitmap bitmap) {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmap.compress(CompressFormat.PNG, 70, stream);
        return stream.toByteArray();
    }

    private String getBase64(Bitmap bitmap) {
        String imgString = Base64.encodeToString(getBytesFromBitmap(bitmap),
                Base64.NO_WRAP);
        return imgString;
    }

デコード

String retrievedBase63 = client2
                .getBaseURI("restaurantFoods/OneFood/" + 5 + "/getImage");
        //Log.d("image", image);
        byte[] decodedString = Base64.decode(retrievedBase63, Base64.DEFAULT);
        Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0,
                decodedString.length);
4

1 に答える 1

1

また、SQL Server 2008 r2 で jdbc に保存された png 画像についてコメント (および応答) したように、古いバージョンの SQL Server では と に対して 8kb の制限がvarbinaryありvarcharました。getBytesドライバーがまたはをサポートしていないかgetString、古い JDBC ドライバーを使用している可能性があります。java.sql.types.LONGVARBINARY別の可能性として、OUT パラメータを(または)として登録する必要がありますLONGVARCHAR

いずれにせよ(他の質問でも)、データを保存する前に最初にbase64でエンコードするのはなぜだろうと思っています。生のバイトをVARBINARY.

于 2013-06-08T08:50:25.610 に答える