java – Abrir galería desde ImageView en NavigationDrawer

Estoy tratando de abrir la galería desde el ImageView situado en el NavigationDrawer pero no he conseguido hacerlo, no sale ningún error pero tampoco sucede algo. Es decir, al presionar el ImageView no sucede absolutamente nada y el LogCat no muestra nada tampoco. Este es el xml donde se sitúa el ImageView:

nav_header_main.xml: 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="@dimen/nav_header_height"
    android:background="@drawable/side_nav_bar"
    android:gravity="bottom"
    android:orientation="vertical"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:theme="@style/ThemeOverlay.AppCompat.Dark">

    <androidx.cardview.widget.CardView
        android:layout_width="65dp"
        android:layout_height="65dp"
        app:cardCornerRadius="75dp"
        android:layout_margin="5dp">
        <ImageView
            android:layout_gravity="center"
            android:id="@+id/ivLogoCambiable"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/white"
            android:scaleType="centerCrop"/>
    </androidx.cardview.widget.CardView>

    <TextView
        android:id="@+id/tvNombreTallerMenIzq"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="@dimen/nav_header_vertical_spacing"
        android:textAppearance="@style/TextAppearance.AppCompat.Body1" />

    <TextView
        android:id="@+id/tvFechaHoraTallerMenIzq"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="08:25 14/05/2021" />
</LinearLayout>

En el MainActivity, lo ejecuto así:

  onCreateView
    //resto código
    NavigationView navigationView = findViewById(R.id.nav_view);
    View headerView = navigationView.getHeaderView(0);
    final ImageView foto_perfil = headerView.findViewById(R.id.ivLogoCambiable);
    //final ImageView foto_perfil = binding.navView.getHeaderView(0).findViewById(R.id.ivLogoCambiable);
    try{
        foto_perfil.setOnClickListener(v -> {
            Toast.makeText(this, "Funciona", Toast.LENGTH_SHORT).show();
            //Intent abrir_galeria = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            //abrir_galeria.setType("image/*");
            //startActivityForResult(abrir_galeria, 1);
        });
    }catch (Exception exception){
        Log.d("TAG", "cambiar_imagen: " + exception.getMessage());
    }

Cómo ven, añadí un Toast para ver si me lo mostraba al presionar la imagen, pero tampoco me lo muestra. ¿Alguien me dice cómo hacerlo de manera correcta o qué es lo que estoy haciendo mal?

android – Permissões não Visualizadas + Galeria e Câmera não abrem

Preciso muito da ajuda de vocês. Abraço.

Não estou conseguindo que o App traga as autorizações e consequentemente não consigo acessar a Classe ConfiguracoesActivity. Pelo menos não pela instalação direta do apk (loja Google e local) e nem completa por Debug pelo Android Studio.

Ela só vem a ser visualizada por depuração linha à linha.

Se eu autorizo manualmente no celular (câmera e arquivos), quando na instalação direta do apk ou instalação pelo Android Studio, consigo acessar a classe, mas, não consigo utilizar a Câmera e nem a Galeria. Volta para activity anterior ao clicar em ambos os botões e sem log de erro que possa ajudar.

Estou testando direto no celular com Android versão 10, API 29. Já tentei desinstalar também e não resolveu.

Segue o log-cat no momento do click:

Click Botão Câmera

E/ViewRootImpl: sendUserActionEvent() mView returned.
E/ViewRootImpl: sendUserActionEvent() mView returned.
E/BufferQueueProducer: (com.amrcodeti.course.empresa/com.amrcodeti.course.empresa.activity.ConfiguracoesActivity$_1742#0) disconnect: not connected (req=1)
E/WindowManager: win=Window{d1ff591 u0 com.amrcodeti.course.empresa/com.amrcodeti.course.empresa.activity.ConfiguracoesActivity} destroySurfaces: appStopped=true win.mWindowRemovalAllowed=false win.mRemoveOnExit=false win.mViewVisibility=8 caller=com.android.server.wm.AppWindowToken.destroySurfaces:1190 com.android.server.wm.AppWindowToken.destroySurfaces:1171 com.android.server.wm.AppWindowToken.notifyAppStopped:1226 com.android.server.wm.ActivityRecord.activityStoppedLocked:2579 com.android.server.wm.ActivityTaskManagerService.activityStopped:2356 android.app.IActivityTaskManager$Stub.onTransact:2183 android.os.Binder.execTransactInternal:1021

Click Botão Galeria

E/ViewRootImpl: sendUserActionEvent() mView returned.
E/ViewRootImpl: sendUserActionEvent() mView returned.
E/BufferQueueProducer: (com.amrcodeti.course.empresa/com.amrcodeti.course.empresa.activity.ConfiguracoesActivity$_1742#0) disconnect: not connected (req=1)
E/WindowManager: win=Window{1ebc8b3 u0 com.amrcodeti.course.empresa/com.amrcodeti.course.empresa.activity.ConfiguracoesActivity} destroySurfaces: appStopped=true win.mWindowRemovalAllowed=false win.mRemoveOnExit=false win.mViewVisibility=8 caller=com.android.server.wm.AppWindowToken.destroySurfaces:1190 com.android.server.wm.AppWindowToken.destroySurfaces:1171 com.android.server.wm.AppWindowToken.notifyAppStopped:1226 com.android.server.wm.ActivityRecord.activityStoppedLocked:2579 com.android.server.wm.ActivityTaskManagerService.activityStopped:2356 android.app.IActivityTaskManager$Stub.onTransact:2183 android.os.Binder.execTransactInternal:1021

Class ConfiguraçõesActivity

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import android.Manifest;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.ImageDecoder;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

import dmax.dialog.SpotsDialog;

public class ConfiguracoesActivity extends AppCompatActivity {

    private String() permissoesNecessarias = new String(){
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.CAMERA
    };
    private ImageButton imageButtonCamera, imageButtonGaleria;
    private static final int SELECAO_CAMERA  = 100;
    private static final int SELECAO_GALERIA = 200;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_configuracoes);
        
        //Validar permissões
        Permissao.validarPermissoes(permissoesNecessarias, this, 1);

        imageButtonCamera  = findViewById(R.id.imageButtonCamera);
        imageButtonGaleria = findViewById(R.id.imageButtonGaleria);
         

        imageButtonCamera.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                if ( i.resolveActivity(getPackageManager()) != null ){
                    startActivityForResult(i, SELECAO_CAMERA );
                }
            }
        });


        imageButtonGaleria.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI );
                if ( i.resolveActivity(getPackageManager()) != null ){
                    startActivityForResult(i, SELECAO_GALERIA );
                }
            }
        });
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if ( resultCode == RESULT_OK ){
            Bitmap imagem = null;

            try {    
                switch ( requestCode ){

                    case SELECAO_CAMERA:
                        imagem = (Bitmap) data.getExtras().get("data");
                        break;

                    case SELECAO_GALERIA:

                        Uri localImagemSelect = data.getData();
                        
                        if (android.os.Build.VERSION.SDK_INT >= 29){
                            // Para uso da depreciação em versões mais novas
                            imagem = ImageDecoder.decodeBitmap(ImageDecoder.createSource(getContentResolver(), localImagemSelect));
                        } else{
                            // Para uso de versões anteriores (getBitmap = depreciada)
                            imagem = MediaStore.Images.Media.getBitmap(getContentResolver(), localImagemSelect);
                        }
        
                        break;
                    }
             //Implementação para salvar a imagem omitida (o problema é acessar a galeria e a câmera)

             }catch (Exception e){
                
                exibirMensagem("Erro ao salvar Imagem: n" + e.getMessage());

        }
    }


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String() permissions, @NonNull int() grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        for ( int permissaoResultado : grantResults ){
            if ( permissaoResultado == PackageManager.PERMISSION_DENIED ){
                alertaValidacaoPermissao();
            }
        }
    }

    private void alertaValidacaoPermissao(){ …    
    }
}

Class Permissão

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;

import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import java.util.ArrayList;
import java.util.List;

public class Permissao {

    public static boolean validarPermissoes(String() permissoes, Activity activity, int requestCode){

        if (Build.VERSION.SDK_INT >= 23 ){

            List<String> listaPermissoes = new ArrayList<>();

            /*Percorre as permissões passadas,
            verificando uma a uma
            * se já tem a permissao liberada */
            for ( String permissao : permissoes ){
                Boolean temPermissao = ContextCompat.checkSelfPermission(activity, permissao) == PackageManager.PERMISSION_GRANTED;
                if ( !temPermissao ) listaPermissoes.add(permissao);
            }

            /*Caso a lista esteja vazia, não é necessário solicitar permissão*/
            if ( listaPermissoes.isEmpty() ) return true;
            String() novasPermissoes = new String( listaPermissoes.size() );
            listaPermissoes.toArray( novasPermissoes );

            //Solicita permissão
            ActivityCompat.requestPermissions(activity, novasPermissoes, requestCode ); 
        }
        return true;
    }
}

Manifest

<uses-feature
        android:name="android.hardware.camera2"
        android:required="false" /> <!-- Loja Google não disponibiliza mais instalação com "true" -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.CAMERA" />

javascript – No carga la imagen subida desde la galería CRUD (IONIC)

Estoy creando una aplicación con estructura CRUD. Subir una imagen desde la galería y que se guarde.
Tengo una imagen puesta por defecto pero al elegir una foto de la galería se debería cambiar. No obstante, se me sube en el Firebase pero con la imagen por defecto y no la foto.

La aplicación lo que debería de hacer es: hay una imagen por defecto (un icono) que sale siempre. El usuario escoge una foto de su galería para subirla y que se guarde automaticamente en Firebase. Pero la cuestión es que se sube pero con la imagen por defecto (el icono) y no con la foto elegida.
Os dejo el código:

  fileLoader: any;
  items: Array<any>;
   validations_form: FormGroup;
  image:any; 
  loading: any;
public myPhotosRef: any;
  public myPhoto: any;
  public myPhotoURL: any;
  nombre:any;
  uploadFirebase: any;
  setProgress: any;
 

  
  alertCtrl: AlertController;
  processing:boolean;
  uploadImage: string ="./assets/imgs/friends-icon.png";
  captureDataUrl: string;
  encodeImageUri:any;
  key: string;
  name: string;
  url: string;
  file: File;
  imagePath: string;
 

  constructor(
    private navCtrl: NavController,
    private modalCtrl: ModalController,
    private authService: AuthService,
    private viewCtrl: ViewController,
    private toastCtrl: ToastController,
    private formBuilder: FormBuilder,
    private imagePicker: ImagePicker,
    private firebaseService: FirebaseService,
    private loadingCtrl: LoadingController

  ) {
    this.loading = this.loadingCtrl.create();
   


  }


  ionViewDidLoad() {
    console.log('ionViewDidLoad ModalnuevositioPage');
  }

  cerrar(){
    let result="se cerró";
    this.viewCtrl.dismiss({result:result});
  }



  ionViewWillEnter(){
    this.getData();
  }

  getData(){
    this.firebaseService.getTasks()
    .then(tasks => {
      this.items = tasks;
    })
  }

  viewDetails(id, item){
    // debugger
    let data = {
      title: item.title,
      description: item.description,
      image: item.image,
      id: id
    }
    this.navCtrl.push(DetailsPage, {
      data: data
    })
  }

  openNewUserModal(){
    let modal = this.modalCtrl.create(ModalnuevositioPage);
    modal.onDidDismiss(data => {
      this.getData();
    });
    modal.present();
  } 

  presentActionSheet(fileLoader) {
      fileLoader.click();
      var that = this;
      fileLoader.onchange = function () {
        var file = fileLoader.files(0);
        var reader = new FileReader();

        reader.addEventListener("load", function () {
          that.processing = true;
          that.getOrientation(fileLoader.files(0), function (orientation) {
            if (orientation > 1) {
              that.resetOrientation(reader.result, orientation, function (resetBase64Image) {
                that.uploadImage = resetBase64Image;
              });
            } else {
              that.uploadImage = reader.result as string;
            }
          });
        }, false);

        if (file) {
          reader.readAsDataURL(file);
        }
      }
    this.uploadImageToFirebase(that.uploadImage);
    }


 
  imageLoaded(){
    this.processing = false;
  }
  getOrientation(file, callback) {
    var reader = new FileReader();
    reader.onload = function (e:any) {

      var view = new DataView(e.target.result);
      if (view.getUint16(0, false) != 0xFFD8) return callback(-2);
      var length = view.byteLength, offset = 2;
      while (offset < length) {
        var marker = view.getUint16(offset, false);
        offset += 2;
        if (marker == 0xFFE1) {
          if (view.getUint32(offset += 2, false) != 0x45786966) return callback(-1);
          var little = view.getUint16(offset += 6, false) == 0x4949;
          offset += view.getUint32(offset + 4, little);
          var tags = view.getUint16(offset, little);
          offset += 2;
          for (var i = 0; i < tags; i++)
            if (view.getUint16(offset + (i * 12), little) == 0x0112)
              return callback(view.getUint16(offset + (i * 12) + 8, little));
        }
        else if ((marker & 0xFF00) != 0xFF00) break;
        else offset += view.getUint16(offset, false);
      }
      return callback(-1);
    };
    reader.readAsArrayBuffer(file);
  }
  resetOrientation(srcBase64, srcOrientation, callback) {
    var img = new Image();

    img.onload = function () {
      var width = img.width,
        height = img.height,
        canvas = document.createElement('canvas'),
        ctx = canvas.getContext("2d");

      // set proper canvas dimensions before transform & export
      if (4 < srcOrientation && srcOrientation < 9) {
        canvas.width = height;
        canvas.height = width;
      } else {
        canvas.width = width;
        canvas.height = height;
      }

      // transform context before drawing image
      switch (srcOrientation) {
        case 2: ctx.transform(-1, 0, 0, 1, width, 0); break;
        case 3: ctx.transform(-1, 0, 0, -1, width, height); break;
        case 4: ctx.transform(1, 0, 0, -1, 0, height); break;
        case 5: ctx.transform(0, 1, 1, 0, 0, 0); break;
        case 6: ctx.transform(0, 1, -1, 0, height, 0); break;
        case 7: ctx.transform(0, -1, -1, 0, height, width); break;
        case 8: ctx.transform(0, -1, 1, 0, 0, width); break;
        default: break;
      }

      // draw image
      ctx.drawImage(img, 0, 0);

      // export base64
      callback(canvas.toDataURL());
    };

    img.src = srcBase64;
  }
  removePic() {
    this.uploadImage = null;
 
}
ionViewWillLoad(){
    this.resetFields()
  }

  resetFields(){
    this.image = "./assets/imgs/default_image.jpg";
    this.validations_form = this.formBuilder.group({
      title: new FormControl('', Validators.required),
      description: new FormControl('', Validators.required)
    });
  }

  dismiss() {
   this.viewCtrl.dismiss();
  }

  onSubmit(value){
    let data = {
      title: value.title,
      description: value.description,
      image: this.image
    }
    this.firebaseService.createTask(data)
    .then(
      res => {
        this.resetFields();
        this.viewCtrl.dismiss();
      }
    )
  }

  

 uploadImageToFirebase(image){
    this.loading.present();
    image = normalizeURL(image);
    let randomId = Math.random().toString(36).substr(2, 5);

    //uploads img to firebase storage
    this.firebaseService.uploadImage(image, randomId)
    .then(photoURL => {
      this.image = photoURL;
      this.loading.dismiss();
      let toast = this.toastCtrl.create({
        message: 'Image was updated successfully',
        duration: 3000
      });
      toast.present();
      })
  }

}

Sería de gran ayuda que me dierais alguna solución.

Gracias

c# – La galería me regresa al Main – Android

Estoy utilizando este procedimiento para seleccionar una imagen de la galería y cargarla en un ImageView, luego utilizo otro para subir la imagen en el ImageView a Firebase Storage.

Lo tengo repetido en dos clases diferentes ya que cargo imágenes en dos Layouts. Lo tengo en el Main.cs y en el Perfil.cs.

En el Main.cs funciona sin problema, pero en Perfil.cs luego de gatillar el procedimiento me abre la galeria, me deja seleccionar la foto pero al volver a la app para ver la imagen y darle al botón “Subir imagen” me regresa al OnStart() del Main.cs, y no al Perfil.cs.

Como puedo volver a Perfil.cs donde lo deje?

Les comparto el método:

async void SelectPhoto()
        {
            try
            {
                await CrossMedia.Current.Initialize();

                //Device.BeginInvokeOnMainThread();

                if (!CrossMedia.Current.IsPickPhotoSupported)
                {
                    Toast.MakeText(this, "Carga de imagen no permitida por el dispositivo", ToastLength.Short).Show();
                    //Img.Visibility = Android.Views.ViewStates.Gone;
                    return;
                }

                var file = await CrossMedia.Current.PickPhotoAsync(new Plugin.Media.Abstractions.PickMediaOptions
                {
                    PhotoSize = Plugin.Media.Abstractions.PhotoSize.Full,
                    CompressionQuality = 40

                });

                // Convert file to byre array, to bitmap and set it to our ImageView

                imageArray = System.IO.File.ReadAllBytes(file.Path);
                Bitmap bitmap = BitmapFactory.DecodeByteArray(imageArray, 0, imageArray.Length);
                Img = FindViewById<ImageView>(Resource.Id.ImgPerfilRounded);
                Img.SetImageBitmap(bitmap);
                //Img.Visibility = Android.Views.ViewStates.Visible;
            }
            catch (Exception Ex)
            {
                string LineErrorNumber = "Error en linea: " + Ex.StackTrace.Substring(Ex.StackTrace.Length - 7, 7) + "rn" + "Error: " + Ex.Message;
            }
        }

Crear varios grupos de galería de imágenes con Fancybox lightbox en Angular

Buen día, intento crear una galería con Fancybox en la cual tengo unos registros en una tabla y un botón que pueda ver las imágenes que tenga cada registro.

introducir la descripción de la imagen aquí

Creé un arreglo de ejemplo con varios objetos el cual recorro con un *ngFor

public productos = (
    {id: 'prod1', nombre: 'Producto 1', url: 'https://i.blogs.es/07fc5b/el-libro-de-imagenes-3/1366_2000.png'},
    {id: 'prod1', nombre: 'Producto 2', url: 'https://images.ctfassets.net/hrltx12pl8hq/VZW7M82mrxByGHjvze4wu/216d9ff35b6980d850d108a50ae387bf/Carousel_01_FreeTrial.jpg?fit=fill&w=800&h=450'},
    {id: 'prod1', nombre: 'Producto 3', url: 'https://i.blogs.es/055219/photos/450_1000.jpg'},
    {id: 'prod2', nombre: 'Producto 4', url: 'https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcSGP5SugfE1GKFwqO9QfHoesP4I9Oq29IBmfA&usqp=CAU'},
    {id: 'prod2', nombre: 'Producto 5', url: 'https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcSr57jHIaC8E_644lZyDVSoOQ-cTPgod6devA&usqp=CAU'},
    {id: 'prod2', nombre: 'Producto 6', url: 'https://cdn.pixabay.com/photo/2017/05/04/01/15/the-evening-sun-2282607_960_720.jpg'},
  );

Hasta este punto todo funciona bien, me muestra la imagen individualmente por cada elemento que recorre el *ngFor

      <tr *ngFor="let producto of productos">
        <td>{{producto.id}}</td>
        <td>{{producto.nombre}}</td>
        <td>      
          <a data-fancybox href="{{producto.url}}" rel="{{producto.id}}" class="success p-0">
            <button type="button" class="btn btn-secondary">Ver galería de fotos</button>          
          </a>
        </td>
      </tr>             
  

En la documentación de Fancybox menciona que al atributo data-fancybox se le puede agregar un nombre para crear un grupo de imágenes, el cual agrego de esta manera: <a data-fancybox="gallery" ...>, y me crea una galería de 6 imágenes (por los elementos que recorre el *ngFor), lo cual no me sirve en este caso ya que necesito que se muestre las imágenes correspondientes al registro seleccionado.

Entonces se me ocurrió colocar el valor del ID de cada elemento del *ngFor para que me creara dos galerías, es decir, una galería con tres imágenes de ID prod1 y otra galería de tres imágenes con ID prod2 de esta manera:

<a data-fancybox="{{producto.id}}" href="{{producto.url}}" ...>

Lo cual me marca un error:

Uncaught Error: Template parse errors:
Can't bind to 'fancybox' since it isn't a known property of 'a'. ("
      <td>{{producto.nombre}}</td>
      <td>      
        <a (ERROR ->)data-fancybox="{{producto.id}}" href="{{producto.url}}" rel="{{producto.id}}"

Tal parece que no acepta interpolación en el atributo data-fancybox.
¿Como podría resolver este problema? He estado investigando y no he logrado resolver este problema.

Como cobrir com uma cor blocada por cima dos elementos de uma galeria em HTML com CSS?

Existe alguma maneira automática de fazer um shape blocado com uma cor por cima dos elementos HTML?

Neste exemplo eu criei blocos por cima manualmente no CSS, mas veja que não esconde totalmente o texto por baixo:

Elementos carregados:
inserir a descrição da imagem aqui

Elementos carregando:
inserir a descrição da imagem aqui

Através do CSS, poderia pegar os textos, imagens, etc e chapar por cima usando os mesmos elementos passando uma classe por exemplo usando pseudo-elemento before {content:'' ...} ou outra maneira?

html – Galeria de imagem responsiva css

Olá,

Gostaria de criar uma galeria de imagem responsiva como este na imagem abaixo.

Quando diminui a resolução a imagem se mantém no mesmo estilo e alinhamento.

Alguém poderia me ajudar?

Imagem responsiva

php – Cómo programar una galería privada de imágenes?

Cómo podría hacer una galería privada de imágenes donde solo algunos usuarios puedan tener acceso?

Me recomendaron que los guarde en la base de datos como tipo BLOB pero tengo entendido que no es recomendable puesto que puede ralentizar la web al escalar la misma(demasiadas imágenes almacenadas).

Leí por ahí que podrían también almacenarse en el servidor, más recomendable puesto que sería más rápido el procesamiento de las imágenes al visualizarlas, sin embargo el problema está que revisando el código de la página cualquier usuario podría acceder a las imágenes al encontrar la ruta src de la imagen.

Leí que lo recomendable podría ser almacenando las imágenes en una ruta fuera del public y el código php llamaría a la galería previa validación de los usuarios autorizados, pero no tengo idea de cómo hacerlo.

Alguien podría ayudarme, por favor?

Gracias de antemano.