Criptografar e descriptografar imagem usando javascript

0

Pergunta

Meu servidor usando esta função em python para criptografar e descriptografar as imagens em um bytearray formato. Eu quero fazer a mesma criptografia no frontend e enviar para essa função no back-end. como converter este método em JavaScript

def encrypted_decrypted_image(image):
    key = 48
    count = 0
    for index, value in enumerate(image):
        count += 1
        image[index] = value ^ key
        if count == 10:
            break
    return image
2
1

Aqui está como fazê-lo com Array.reduce(),

// def encrypted_decrypted_image(image):
//    key = 48
//    count = 0
//    for index, value in enumerate(image):
//        count += 1
//        image[index] = value ^ key
//        if count == 10:
//            break
//    return image

function xorImage(imageBuffer, key=48){
  return imageBuffer.reduce((acc, value, index) => {
    if(index == 10) return acc;
    acc.push(value ^ key);
    return acc;
  }, [])
}

console.log(xorImage([1, 20, 3, 4, 5, 6, 7, 8, 9]))

2021-11-22 03:07:25

é o parâmetro de entrada imageBuffer é arraybuffer ou bytearray?
Ali Ouda

porque a minha entrada é um byteArray
Ali Ouda
1

Para obter pixels individuais de componentes a partir de uma imagem, você deve primeiro desenhar a imagem na tela:

const image = document.getElementById('image');
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
const width = image.width;
const height = image.height;

canvas.width = width;
canvas.height = height;

// Draw original image: 
context.drawImage(image, 0, 0, width, height);

Em seguida, obter os valores para os pixels que você está indo para a atualização:

const data = context.getImageData(0, 0, width, height).data;

Observar a forma e o tipo de dados retornado pelo CanvasRenderingContext2D.getImageData() função:

ImageData ctx.getImageData(sx, sy, sw, sh);
  • sx: A coordenada x do canto superior esquerdo do retângulo a partir do qual o ImageData serão extraídos.
  • sy: A coordenada y do canto superior esquerdo do retângulo a partir do qual o ImageData serão extraídos.
  • sw: A largura do retângulo do que o ImageData serão extraídos.
  • sh: A altura do retângulo a partir do qual o ImageData serão extraídos.

Você pode ver que ele retorna um ImageData objeto, o que quer que seja. A parte importante aqui é que o objeto tem um .data propriedade que contém todos os nossos valores de pixel.

No entanto, observe que .data propriedade é um 1-dimensão Uint8ClampedArray, o que significa que todos os pixel componentes foram arrasados, então você está recebendo algo que se parece com isso:

Vamos dizer que você tem um 2x2 imagem como esta:

 RED PIXEL |       GREEN PIXEL
BLUE PIXEL | TRANSPARENT PIXEL

Então, você vai buscá-los assim:

[ 255, 0, 0, 255,    0, 255, 0, 255,    0, 0, 255, 255,    0, 0, 0, 0          ]
|   RED PIXEL   |    GREEN PIXEL   |     BLUE PIXEL   |    TRANSPAERENT  PIXEL |
|   1ST PIXEL   |      2ND PIXEL   |      3RD PIXEL   |             4TH  PIXEL | 

Em seguida, você pode transformar esses valores, no entanto, você gostaria, e no seu caso de uso específico, que seria tudo o que você precisa fazer no frontend antes de enviar os dados transformados para o servidor:

const transformedData = encryptedDecryptedImage(data);

fetch('httsp://', { ... });

Se você quiser desenhar os dados transformados de volta na página, você primeiro precisa convertê-lo de volta para ImageData usando CanvasRenderingContext2D.createImageData() e CanvasRenderingContext2D.putImageData():

const imageData = context.createImageData(width, height);

imageData.data.set(new Uint8ClampedArray(transformedData));

context.putImageData(transformedData, 0, 0);

Exemplo de trabalho:

const image = document.getElementById('image');
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
const width = image.width;
const height = image.height;

canvas.width = width;
canvas.height = height;

// Draw original image: 
context.drawImage(image, 0, 0, width, height);

// Transform the top half of the image (each pixel has 4 coordinates, RGB and alpha):
const maxTransformedCoords = width * Math.round(height / 2) * 4; 

// Avoid processing more than needed:
const requiredRows = Math.ceil(maxTransformedCoords / (width * 4));

// Get the pixel component values as an array:
const data = context.getImageData(0, 0, width, requiredRows).data;

// Your transform logic (with some changes):

const key = 48;

let count = 0;

const transformedData = data.map((value, i) => {    
  if (++count > maxTransformedCoords) return value;

  // Turn alpha coordinates opaque:
  // if ((i + 1) % 4 === 0) return 255;

  // Your logic:
  return value ** key;
});

// Turn the transformed data into an ImageData object:
const imageData = context.createImageData(width, requiredRows);
imageData.data.set(new Uint8ClampedArray(transformedData));

// Draw the transformed pixels:
context.putImageData(imageData, 0, 0);

// Display it on the page:
canvas.id = 'canvas';
document.body.append(canvas);
body {
  margin: 0;
  height: 100vh;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  font-family: monospace;
  overflow: hidden;
}

#image,
#canvas {
  border: 4px solid white;
  border-radius: 2px;
  box-shadow: 0 0 32px 0 rgba(0, 0, 0, .25);
  width: 150px;
  box-sizing: border-box;
  display: block;
  background: cyan;
}

#canvas {
  margin-left: 32px;
}
<img id="image" src="data:image/gif;base64,R0lGODlhSwBLAPEAACMfIO0cJAAAAAAAACH/C0ltYWdlTWFnaWNrDWdhbW1hPTAuNDU0NTUAIf4jUmVzaXplZCBvbiBodHRwczovL2V6Z2lmLmNvbS9yZXNpemUAIfkEBQAAAgAsAAAAAEsASwAAAv+Uj6mb4A+QY7TaKxvch+MPKpC0eeUUptdomOzJqnLUvnFcl7J6Pzn9I+l2IdfII8DZiCnYsYdK4qRTptAZwQKRVK71CusOgx2nFRrlhMu+33o2NEalC6S9zQvfi3Mlnm9WxeQ396F2+HcQsMjYGEBRVbhy5yOp6OgIeVIHpEnZyYCZ6cklKBJX+Kgg2riqKoayOWl2+VrLmtDqBptIOjZ6K4qAeSrL8PcmHExsgMs2dpyIxPpKvdhM/YxaTMW2PGr9GP76BN3VHTMurh7eoU14jsc+P845Vn6OTb/P/I68iYOfwGv+JOmRNHBfsV5ujA1LqM4eKDoNvXyDqItTxYX/DC9irKBlIhkKGPtFw1JDiMeS7CqWqySPZcKGHH/JHGgIpb6bCl1O0LmT57yCOqoI5UcU0YKjPXmFjMm0ZQ4NIVdGBdZRi9WrjLxJNMY1Yr4dYeuNxWApl1ALHb+KDHrTV1owlriedJgSr4Cybu/9dFiWYAagsqAGVkkzaZTAuqD9ywKWMUG9dCO3u2zWpVzIhpW122utZlrHnTN+Bq2Mqrlnqh8CQ+0Mrq3Kc++q7eo6dlB3rLuh3abPVbbbI2mxBdhWdsZhid8cr0oy9F08q0k5FXSadiyL1mF5z51a8VsQOp3/LlodkBfzmzWf2bOrtfzr48k/1hupDaLa9rUbO+zlwndfaOCURAXRNaCBqBT2BncJakWfTzSYkmCEFr60RX0V8sKaHOltCBJ1tAAFYhHaVVbig3jxp0IBADs=" >

⚠️ Nota que eu estou usando um pequeno URI de dados para evitar Cross-Origin problemas se eu incluir uma imagem externa ou uma resposta que é maior do que o permitido, se eu tentar usar mais dados URI.

2021-11-22 03:30:25

Eu estou usando isso para gravar blocos de media recorder eu quero saber se eu posso usar esta blocos como o meu de entrada para a codificação : mediaRecorder.ondataavailable = function (e) { if (p.dados.tamanho > 0) { recordedChunks.push(p.de dados); } }
Ali Ouda

Este exemplo irá funcionar bem com um pedaço de cada vez, assumindo que contém uma matriz unidimensional onde os dados de pixel já foi achatada. Caso contrário, você teria que fazer isso primeiro. Ver onde eu explicar o valor de retorno de getImageData().
Danziger

Em outros idiomas

Esta página está em outros idiomas

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................