Szyfrowanie i deszyfrowanie plików obrazu za pomocą javascript

0

Pytanie

Mój serwer korzysta z tej funkcji w języku python do szyfrowania i deszyfrowania zdjęć w formacie bytearray. Chcę zrobić to samo szyfrowanie w zewnętrznym interfejsie i wysłać tę funkcję w backend. jak przekształcić ten metoda w 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

Oto jak to zrobić za pomocą 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

czy parametr wejściowy imageBuffer arraybuffer lub bytearray?
Ali Ouda

bo mój wkład to байтрейд
Ali Ouda
1

Aby uzyskać poszczególne składniki pikseli z obrazu, najpierw trzeba narysować obraz na płótnie:

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

Następnie otrzymasz wartości pikseli, które chcesz zaktualizować:

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

Zwróć uwagę na kształt i typ danych zwracanych przezCanvasRenderingContext2D.getImageData() funkcja:

ImageData ctx.getImageData(sx, sy, sw, sh);
  • sx: Współrzędna x lewego górnego rogu prostokąta, z którego będą pobierane dane obrazu.
  • sy: Współrzędna y lewego górnego rogu prostokąta, z którego będą pobierane dane obrazu.
  • sw: Szerokość prostokąta, z którego będą pobierane dane obrazu.
  • sh: Wysokość prostokąta, z którego będą pobierane dane obrazu.

Widać, że on zwraca ImageData obiekt, co by to nie było. Ważną częścią polega na tym, że ten obiekt ma .data właściwość, która zawiera wszystkie nasze wartości pikseli.

Należy jednak pamiętać, że .data właściwość jest 1-wymiaroweUint8ClampedArray, co oznacza, że wszystkie składniki piksela zostały wygładzone, tak, że można dostać coś podobnego do tego:

Załóżmy, że masz obraz 2x2, coś podobnego do tego:

 RED PIXEL |       GREEN PIXEL
BLUE PIXEL | TRANSPARENT PIXEL

Wtedy dostaniesz je tak:

[ 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 | 

Następnie można przekonwertować te wartości tak, jak chcesz, i w twoim konkretnym przypadku to będzie wszystko, co musisz zrobić na interfejsie przed wysłaniem przekonwertowanych danych na serwer:

const transformedData = encryptedDecryptedImage(data);

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

Jeśli chcesz odzyskać przekonwertowane dane na stronę, musisz najpierw przekształcić je z powrotem doImageData z pomocąCanvasRenderingContext2D.createImageData() iCanvasRenderingContext2D.putImageData():

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

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

context.putImageData(transformedData, 0, 0);

Praktyczny przykład:

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=" >

⚠️ Uwaga używam małej URI danych, aby uniknąć Cross-Origin problem, gdy włączam obraz zewnętrzny lub odpowiedź, której rozmiar przekracza dopuszczalny, jeśli staram się używać dłużej URI danych.

2021-11-22 03:30:25

Używam go do nagrywania fragmentów z nagrywarki multimedialne, chcę wiedzieć, czy mogę wykorzystać te fragmenty jako danych wejściowych do szyfrowania : MediaRecorder.ondataavailable = funkcja (e) { jeśli (na przykład dane.rozmiar > 0) { Nagrane fragmenty.push(np. dane); } }>
Ali Ouda

Ten przykład będzie dobrze pracować z jednym fragmentem na raz, jeśli założyć, że zawiera on tablicą jednowymiarową, w którym dane pikseli już wygładzone. W przeciwnym razie trzeba by było zrobić to w pierwszej kolejności. Zobacz, gdzie tłumaczę wartość zwracana getImageData().
Danziger

W innych językach

Ta strona jest w innych językach

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