0

JIRA билетов, созданный из-за отказа base64encode: https://jira.appcelerator.org/browse/TC-5876Невозможно сделать изображение Blob JSON Serializable

Мой текущий CFG: Titanium SDK 5.1.2.GA Тестирование на iPhone IOS 9.1

Я нахожусь застрял в проблеме в проекте для клиента, который требует, чтобы изображения принимались на устройстве (с помощью камеры), которое отправлялось в WebService, а затем просматривалось на любом устройстве с помощью приложения (как на устройствах Android, так и на iOS). Titanium предоставляет объект Ti.Blob (event.media) после снимка (который не является сериализуемым JSON), и мне нужно как-то отправить его на сервер. Сервер всегда отвечает за объект JSON, поэтому этот Blob должен быть как-то сериализуемым JSON.

Я пробовал много способов без успеха:

1 - Base64Encode блоб

var base64blob = Ti.Utils.base64encode(event.media); 

не работает, это заклинивание приложение и бросает ASL ​​превышена максимальная погрешность размера. Я полагаю, что изображение слишком велико, чтобы быть base64encoded.

2 - Прочитайте Blob в буфер

var blobStream = Ti.Stream.createStream({ source: event.media, mode: Ti.Stream.MODE_READ }); 
var buffer = Ti.createBuffer({ length: event.media.length }); 
var bytes = blobStream.read(buffer); 

Это работает, но я понятия не имею, как я могу преобразовать этот буфер держа содержимое образа в то, что сервер может вернуться в объект JSON, а затем быть снова превратился в Image Blob.

Сервер не может управлять объектами Ti.Blob или объектами Ti.Buffer, поскольку, прежде всего, это объекты Titanium, а сервер - на C#, а второй - из Ti.Blob и Ti.Buffer. JSON сериализуется, поэтому возврат JSON не работает.

Что мне нужно в основном описано в воображаемом примере ниже:

var imageBlob = event.media; 
var JSONSerializableImg = imageBlob.toJSON(); 
sendImageToServer(JSONSerializableImg); 

var imgFromServer = getImageFromServer(); 
var imageBlob = imgFromServer.toBlob(); 
var imgView = createImageView({ 
    image: imageBlob 
}); 

Я надеюсь, что кто-то может помочь мне с каким-либо методом преобразования возможно.

Спасибо-х

+0

Я ничего не знаю о Ti.BLOB. Но BLOB должен быть двоичным большим объектом. Итак, если вы консолируете запись BLOB, я бы предположил, что вы получаете двоичную строку. Вы могли: a) попытаться передать эту строку в объект JS: {blob: [BINARY]}, а затем использовать JSON.stringify (object) и отправить его на сервер. На стороне сервера вы можете попробовать и проанализировать двоичный файл и, используя SQL, вставить его в объект BINARY (MAX) или VARCHAR (MAX). Обратный процесс для просмотра. b) разбить BLOB на несколько меньших массивов и нажимать каждый отдельно с приложением и реорганизовывать его на сервер, а затем хранить. – Rouse02

+0

Вы говорите, что «сервер всегда отвечает за объект JSON», но что принимает ваш сервер? Вы загружаете свое изображение, например. многостраничная загрузка? Или любой другой? У вас есть больше информации о вашей конечной точке, на которую вы загружаете изображения? – davidcyp

+0

@ Rouse02 Ti.Blob - это объект, принадлежащий Titanium API (см. Это: http://docs.appcelerator.com/platform/latest/#!/api/Titanium.Blob). Я могу извлечь его содержимое в буфер и затем декодировать его с помощью Ti.Codec (см. Это: http://docs.appcelerator.com/platform/latest/#!/guide/Buffer_and_Codec) Как вы думаете, я могу JSON. что-то с помощью этих объектов? Я знаю, что вы не знаете Титана, но, возможно, вы посмотрите на документацию, вы можете найти решение. –

ответ

0

Я решил эту проблему, создав отдельный способ на серверной стороне специально для загрузки фотографий. Я по ссылке ниже для серверной стороны:

PHP code

В Titanium я должен был установить заголовок XHR как это:

this.xhr.setRequestHeader("ContentType", "image/png"); this.xhr.setRequestHeader('enctype', 'multipart/form-data');

Вот так! Спасибо за все ответы.

-2

Я использовал следующий метод перед (не в титане, а другой веб-мобильная платформа приложение).

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

convertToDataURLviaCanvas('http://example.com/image.png', function(base64Img){ 
    // Base64DataURL 
}); 

Я использовал это, чтобы отправить строку кодированного изображения base64 как JSON на мой серверный сервер. Затем повторно закодировано изображение на сервере. Это сработало для меня, но строка с кодировкой base64 огромна.

+0

Работает ли он с двоичными данными (blob) вместо URL? Мне нужно получить изображение с устройства камеры. –

+1

FYI, код выше не будет работать в приложении Titanium. Нет DOM, нет документа, нет объекта Image и Canvas. –

+0

Правильно @ChrisBarber это не сработает, но спасибо Rossman66 за помощь. –

1

OK,

Это то, что я думаю, что вы должны сделать. Глядя на API, это очень удобно.

1: Вам необходимо создать объект на стороне сервера, который будет удерживать BLOB.

public class BlobContainer 
{ 
    public string fileName{get;set;} 
    //... (Other properties) 
    public byte[] data {get;set;} 
} 

2: Преобразование важной информации из BLOB в двоичный массив и отправка на сервер.

var blobStream = Ti.Stream.createStream({ source: myBlob, mode: Ti.Stream.MODE_READ }); 
var newBuffer = Ti.createBuffer({ length: myBlob.length }); 
var bytes = blobStream.read(newBuffer); 

3: Затем отправьте данные байта на сервер через запросы Ajax.Помните, насколько большой ваш массив, который вы отправляете. Это может быть выгодно, чтобы разделить массив и объединить его с другой стороны (могут не потребоваться):

var dataObjects: [ 
    { id: 1, data: [BYTE_DATA_PART] }, 
    { id: 2, data: [BYTE_DATA_PART] }... 
] 
$.each(dataObjects, function(i,a) { 
    $.ajax({ url: "BLA", data: JSON.stringify(a), dataType: "json", type: "POST", 
     success: function() { //CONTINUE\\ }, 
     error: function() {alert("ERROR BRO"}) 
    }); 
}); 

4: Затем на сторону сервера получить каждый запрос в вашем маленьком блоб контейнере, хранить в объекте сеанса или кеш-объект, и как только у вас будет N из N, объедините все это и сохраните эту присоску в базе данных.

5: Извлеките материал в обратном порядке. Просто помните, что он хранится как данные байта []. Возможно, вам придется с этим смириться и сохранить его как строку из-за того, как буфер TI создает байты и способ, которым C# интерпретирует байты. Лучше всего проб и ошибок. Как только у вас появятся все части на клиенте.

var newBuffer = Ti.Stream.read(data, 0, data.length); 
var newBlob = newBuffer.toBlob(); 
+0

Это возможное решение, проблема заключается в шаге 2, код, который вы написали, просто берет BLOB-информацию в Ti.Buffer (объект Titanium). Он по-прежнему не является двоичным массивом. Как я могу извлечь этот двоичный массив, чтобы я мог отправить на сервер, как вы упомянули? –

+0

Вы используете var bytes = blobStream.read (newBuffer); Это должно взять буфер и вернуть массив байтов. – Rouse02

+0

Это не так, он просто возвращает количество прочитанных байтов. Я и парень, ответственный за сервер, пытаются что-то выяснить. Глядя на ссылку ниже, я обнаружил, что Ti.Buffer может быть доступен как массив stantard (например, буфер [0]), но это не значит, что это массив. Это проблема. http://docs.appcelerator.com/platform/latest/#!/guide/Buffer_and_Codec Важно отметить, что буфер имеет приблизительно 9000000 байт. Невозможно, чтобы я со стороны мобильного приложения зацикливал этот буфер и отправлял его на сервер. Я тестировал здесь, и это занимает несколько минут. –

0

Для отправки и получения двоичных данных и с сервера лучше всего использовать Ti.Network.HTTPClient, которые могут отправлять и получать двоичные данные.

Там есть руководство по загрузке и скачивании файлов здесь: http://docs.appcelerator.com/platform/latest/#!/guide/File_Uploads_and_Downloads

JSON isn't designed нести бинарные данные, хотя base64encoded двоичные данные должны работать. Это то, что действительно есть для Ti.Utils.base64encode(). Если вы считаете, что «ASL превысила максимальную ошибку размера», вы получите не должно быть, пожалуйста, создайте билет на Appcelerator JIRA

+0

JIRA билет включено в мой вопрос. https://jira.appcelerator.org/browse/TC-5876 –

Смежные вопросы