ugrás a tartalomhoz

Blob kép megjelenítése adatbázisból Codeigniter-el

csozo · 2011. Aug. 2. (K), 16.49
Sziasztok!

Codeigniterben jártas személyektől szeretnék segítséget kérni. Adatbázisban tárolok képeket BLOB formátumban, attól most tekintsünk el, hogy célszerűbb a kép útvonalát tárolni, jelen esetben muszáj BLOB-ban tárolnom és onnan kiolvastatnom. Az adatbázis szintén adott, semmit nem változtathatok rajt,
CREATE TABLE `aru` (
`cikksz` Varchar(20) NOT NULL,
`megnev` Varchar(255) NOT NULL,
`ar` INTEGER UNSIGNED,
`index_kep` LONGBLOB,
`kep` LONGBLOB,
PRIMARY KEY(`cikksz`)
)
TYPE = InnoDB;
A feladatom az lenne, hogy az index kép csak akkor töltődjön le, ha az valóban látszik is a böngészőablakban (felesleges requestek minimalizálása), továbbá a nagy képet csak akkor kérje le és mutassa meg egy új layer-en (fancybox, lightbox, ami szimpatikus), amikor a felhasználó rákattint az index képre.
A problémám az lenne, hogy az adatbázisból lekérem a képeket, de kiíratáskor mindenféle zagyvaság jelenik meg a kép helyén. Több helyen olvastam, hogy a header információkat kell megváltoztatni kiíratás előtt így,
header('Content-type: image/jpeg');
de nálam, amint megadom ezt a sort, az addigi dolgok sem jelennek meg, csak egy tök üres oldal. Próbáltam már így is megadni,
[$this->output->set_header('Content-type: image/jpg');
az eredmény ugyanaz. Olvastam még olyan lehetséges megoldást, miszerint az addslashes() alkalmazása feltöltéskor, és a stripslashes() alkalmazása kiolvasáskor megoldja a problémát. Nálam sajnos ez sem hozott eredményt. Valamint ez nem is lenne jó esetemben, mivel nem kell konkrét feltöltő formot készítenem, egyszerűen phpMyAdminon keresztül megy minden adat feltöltése, szóval nem is tudnám alkalmazni az előbb említett függvényeket, de egy próbát azért tettem velük.
Hogy tudnám megoldani, hogy megjelenjenek helyesen a képek? Mit csináltam rosszul? A view fájlom, ami megjeleníti az adatokat:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>Untitled</title>
        <script src="http://www.google.com/jsapi"></script>
	<script type="text/javascript">
	google.load("jquery", "1.6.2");
	</script>
        <script type="text/javascript" src="assets/js/pagination.js"></script>
        <script type="text/javascript" src="assets/js/jquery.fancybox-1.3.4.pack.js"></script>
        <script type="text/javascript" src="assets/js/jquery.easing-1.3.pack.js"></script>
        <script type="text/javascript" src="assets/js/jquery.fancybox-1.3.4.js"></script>
        <script type="text/javascript" src="assets/js/jquery.mousewheel-3.0.4.pack.js"></script>
        <script>
            $(document).ready(function() {
                $("a.small_image").fancybox();
            });
        </script>
        <link rel="stylesheet" type="text/css" href="assets/css/style.css" media="screen"/>
        <link rel="stylesheet" href="assets/css/jquery.fancybox-1.3.4.css" type="text/css" media="screen" />
    </head>
    <body>
        <div id="display-content">
            <p class="pagination"><?php echo $pagination."<br />"; ?></p>
            <table>
                <tr>
                        <th width="20%">Cikkszám</th>
                        <th width="40%">Megnevezés</th>
                        <th width="20%">Ár</th>
                        <th width="20%">Index_kép</th>
                </tr>
            <?php
                foreach ($products as $prod){
            ?>
                <tr>
                    <td width="20%"><?php echo $prod->cikksz."<br />"?></td>
                    <td width="40%"><?php echo $prod->megnev."<br />"?></td>
                    <td width="20%"><?php echo $prod->ar."<br />"?></td>
                    <td width="20%">
                        <?php
                            // $this->output->set_header('Content-type: image/jpg'); // Ha a header be van állítva nem jelenít meg semmit, csak üres oldalt. Ha másik fájlban próbálom meg kiiratni, ahol csak az image/jpeg header van beállítva (a kettős MIME type elkerülése miatt), az eredmény ugyanaz.
                            // header('Content-type: image/jpeg'); //másik header lehetőség
                            // $this->output->set_output($prod->index_kep)."<br />";
                            echo anchor($prod->kep, $prod->index_kep, array('class' => 'small_image'));
                        ?>
                    </td>
                </tr>    
           <?php
                }
            ?>
            </table>
        </div><!--End of display-content--> 
    </body>
</html>
Valamint azt tudom, hogy a nagy kép megjelenítése nem lesz jó így
echo anchor($prod->kep, $prod->index_kep, array('class' => 'small_image'));
mert helytelenül hivatkozok rá, szóval örülnék, ha esetleg arra is jönne megoldás, hogy hogyan hivatkozhatnék a kép eredetijére a kiolvasás után, hogy a fancybox megjelenítse.

Előre is köszönöm a segítséget!
 
1

HTML

Poetro · 2011. Aug. 2. (K), 17.17
Eleve nem jól közelíted meg a dolgot. A HTML-be egy image tag kell, ami a te egyik PHP kódodra mutat. Ez teljesen független attól, hogy CodeIgniter vagy nem.

                    <td width="20%">  
                        <a href="valami.php?id=id&size=kep" class="small_image"><img src="valami.php?id=id&size=index_kep">
                    </td>
Ez persze nem tudom, jó-e CodeIgniterben, de valami hasonló.
És ekkor a valami.php majd visszaadja a képet a megfelelő fejlécekkel.
2

Codeignitert ugyan nem

H.Z. v2 · 2011. Aug. 2. (K), 17.22
Codeignitert ugyan nem ismerem, ebből következően megtörténhet, hogy hülyeséget írok.
Nekem úgy tűnik, nálad alapvető ismeretek hiányoznak:
A http headert még az oldal előtt kell kiküldeni. Ha onnan, ahová beraktad, kimegy, az csak annyit jelent, hogy az output buffering be van kapcsolva és még küldés előtt előre kerül a header infó. Ha történetesen egy html lap előtt sikerül kiküldeni egy olyan headert, ami arra utal, hogy most egy kép következik (Content-type: image/jpeg), akkor a mögötte érkező bájtokat a böngésző megpróbálja képként kezelni. Valószínűnek tartom, hogy emiatt nem jelenik meg az oldalad.

Ahol a képet meg akarod jeleníteni, ott egy <img ...> tag kell. A src attribútumban megadhatod annak a php programnak a címét (URL), ami magát a képet nyeri ki az adatbázisból. Na ennek a programnak kell a kimenetét egy Content-type: image/jpeg headerrel indítani és mögötte egy bináris jpeg-et kiküldeni.

upd: na tessék, most négy perccel maradtam le... :-)
3

Köszi szépen

csozo · 2011. Aug. 2. (K), 18.02
Köszi szépen a segítséget, sikerült megoldanom, hogy megjelenjenek az index_képek. :)
Segítségül azoknak, akik hasonló cipőben járnának. A controllerben a következő kódot adtam meg:
public function getsmallpic($product_id){
        $image = $this->db->select('index_kep');
        $image = $this->db->where('cikksz',$product_id);
        $image = $this->db->get('aru');
        $image = $image->row();

        // Show image
        $this->output->set_header('Content-type: image/jpg');
        $this->output->set_output($image->index_kep);
    }
A view fájlban pedig a következőképpen jelenítettem meg:
<td width="20%"><img src="<?php print base_url().'index.php/site/getsmallpic/'.$prod->cikksz; ?>" /></td>
Viszont szeretnék kérdezni még a felesleges requestek minimalizálásáról. Konkrétan ahol nem tároltam indexképet, ott megjeleníti a kis négyzetet, ami jelzi, hogy nem találja a képet. Ezt kellene kiküszöbölnöm, vagyis csak akkor töltődjön le az indexkép, ha az látszik is a böngészőben.
Egyenlőre még az eredeti méretű kép fancyboxos megjelenítésével vacakolok, de holnap délután 4-ig van időm, szerintem összejön ez is, és requestes is, ha kapok hozzá egy kis segítséget. :)
Köszi mégegyszer. :)
4

Feltétel

Poetro · 2011. Aug. 2. (K), 18.05
Mondjuk amikor lekérdezed az adatbázisból az indexképet a HTML oldalon, akkor megnézed, hogy annak van-e valami mérete (szerintem ilyet biztosan ki lehet erőszakolni az adatbázisból, még blob esetén is), vagy eleve NULL-t állítasz be, ha nincs indexkép. Innentől kezdve pedig egy egyszerű feltétel a template-ben.
5

újra köszi

csozo · 2011. Aug. 2. (K), 18.41
Újabb köszönet. :)
Nem nagyon gondoltam végig ezt a requestes dolgot, mert a BLOB aggasztott igazán, de így rátérve már látom, hogy valóban pofonegyszerű a dolog, sima if..else a view-ban, és meg is van oldva. Remek. :)
<?php if ($prod->index_kep){?>
  <img src="<?php print base_url().'index.php/site/getsmallpic/'.$prod->cikksz; ?>" />
<?php
  }
?>
6

Nem szeretnék

csozo · 2011. Aug. 2. (K), 19.37
Nem szeretnék balféknek tűnni, de újabb problémám lenne a fancyboxal a nagyméretű képek megjelenítésekor. Már pár órája a feladat felett ülök, és kissé le vagyok merülve agyilag, lehet megint nem nagy kunszt a probléma, de azért kérdeznék.
Szóval a fancybox az indexképekre kattintáskor elkezdi betölteni a nagyméretű képet, de ugyanúgy a karaktersorozatokat jeleníti meg a kép helyett, akár a getsmallpic(), akár a getoriginalpic() függvényeket hívom meg. Azt gondoltam, hogy ha ugyanúgy hivatkozok a képre a linkben, mint a kép forrása esetén, működni fog, de mint mondom, a kép helyett a karakterek sokasága látszik.
(Megjegyzés: Tudom, hogy két függvény lehetne egyben, és ellenőrizhetném pl a fájlméretet és az alapján lekérhetném a megfelelő képet, de ez gyorsabb megoldásnak tűnt, copy-paste, csak függvény és változónevet kellet módosítani, szigorúan a fáradtság miatt. :P )

Szóval a kérdésem, hogy hogyan oldhatnám meg, ha magában a táblázatban már megfelelően megjelennek az indexképek, akkor fancybox is megjelenítse őket?
Az alábbi módon próbálom meg megjeleníteni őket:
<?php if ($prod->index_kep){?>
   <a class="small_image" href="<?php echo base_url().'index.php/site/getoriginalpic/'.$prod->cikksz; ?>">
      <img src="<?php echo base_url().'index.php/site/getsmallpic/'.$prod->cikksz; ?>" />
   </a>
<?php
 }
?>