Bài viết mới:

Thứ Tư, 15 tháng 8, 2018

Share template bán sách Koparion đẹp + hiện đại không thể chê


Giao diện Koparion được thiết kế bằng HTML5/CSS3 + Bootstrap nên hỗ trợ responsive rất tốt. Đáng lẽ phải mất phí đẻ mua nhưng bây giờ mình share lại nếu cần lấy về làm web kinh doanh hoặc làm đồ án gì đó đều rất ok.
Thấy hay thì chia sẻ cho mọi người cùng biết nhé 👍👍👍.

Thứ Tư, 6 tháng 6, 2018

Cắt hình ảnh (crop image) tự động bằng PHP

Nhu cầu cắt hình ảnh tự động trong những website chứa nhiều hình ảnh như web thương mại điện tử, web tin tức, mạng xã hội chia sẻ hình ảnh là cực kỳ cần thiết. Bài viết này hướng dẫn bạn cắt hình sau khi upload bằng ngôn ngữ PHP để tạo ra nhiều hình ảnh kích thước khác nhau và những hình ảnh đó đều có chất lượng tốt chứ không bị vỡ.

Đây là hàm giúp chúng ta thực hiện công việc đó.

function CreateThumbImage($filenameImage, $filenameThumb, $ext, $thumb_width, $thumb_height)
    {
  if($ext == "jpeg" || $ext == "jpg")
  {
   $image = imagecreatefromjpeg($filenameImage);
  }
  if($ext == "png")
  {
   $image = imagecreatefrompng($filenameImage);
  }
  $filename = $filenameThumb;

  // $thumb_width = 300;
  // $thumb_height = 300;

  $width = imagesx($image);
  $height = imagesy($image);

  $original_aspect = $width / $height;
  $thumb_aspect = $thumb_width / $thumb_height;

  if ( $original_aspect >= $thumb_aspect )
  {
     // If image is wider than thumbnail (in aspect ratio sense)
     $new_height = $thumb_height;
     $new_width = $width / ($height / $thumb_height);
  }
  else
  {
     // If the thumbnail is wider than the image
     $new_width = $thumb_width;
     $new_height = $height / ($width / $thumb_width);
  }

  $thumb = imagecreatetruecolor( $thumb_width, $thumb_height );

  switch ($ext) {
      case 'png':
          // integer representation of the color black (rgb: 0,0,0)
          $background = imagecolorallocate($thumb , 0, 0, 0);
          // removing the black from the placeholder
          imagecolortransparent($thumb, $background);

          // turning off alpha blending (to ensure alpha channel information
          // is preserved, rather than removed (blending with the rest of the
          // image in the form of black))
          imagealphablending($thumb, false);

          // turning on alpha channel information saving (to ensure the full range
          // of transparency is preserved)
          imagesavealpha($thumb, true);
          break;

      default:
          break;
  }

  // Resize and crop
  imagecopyresampled($thumb,
                     $image,
                     0 - ($new_width - $thumb_width) / 2, // Center the image horizontally
                     0 - ($new_height - $thumb_height) / 2, // Center the image vertically
                     0, 0,
                     $new_width, $new_height,
                     $width, $height);
  switch ($ext) {
   case 'jpg':
   case 'jpeg':
   {
    imagejpeg($thumb, $filename, 100);break;
   }
   case 'png':
   {
    imagepng($thumb,$filename,1);break;
   }
   default:
   {
    imagejpeg($thumb, $filename, 100);
   }
  }
 }

Hàm này nhận vào 5 tham số $filenameImage, $filenameThumb, $ext, $thumb_width, $thumb_height. Mình giải thích ý nghĩa 5 tham số này như sau:
  • $filenameImage: đường dẫn hình ban đầu
  • $filenameThumb: đường dẫn chứa hình sau khi cắt
  • $ext: đuôi mở rộng của file hình ban đầu
  • $thumb_width: chiều rộng hình sau khi cắt
  • $thumb_height: chiều cao hình sau khi cắt

Trong bài viết này mình sẽ ví dụ trường hợp upload 1 hình ảnh size 300x300 và chương trình sẽ tự tạo ra thêm 2 hình thumb (size 169x169)small (size 50x50).

Đầu tiên mình có 1 form rất cơ bản như sau trong trang web.

<form role="form" action="http://localhost:8080/cropimage/crop.php" method="post"  enctype="multipart/form-data">
  <input type="file" name="file" />
   <button type="submit">Upload</button>
</form>

Sau đó mình chọn 1 file hình size 300x300x từ máy mình và click submit để server gọi đến file crop.php để xử lý. Đây là nội dung file crop.php

<?php



if(isset($_FILES['file']) && $_FILES['file']['size'] > 0)

        {

          $validextensions = array("jpeg", "jpg", "png");

          $temporary = explode(".", $_FILES["file"]["name"]);

          $file_extension = end($temporary);

          if ((($_FILES["file"]["type"] == "image/png")

          || ($_FILES["file"]["type"] == "image/jpg")

          || ($_FILES["file"]["type"] == "image/jpeg"))//approx. 100kb files can be uploaded

          && in_array($file_extension, $validextensions)) {

            define("SITE_PATH", $_SERVER['DOCUMENT_ROOT'].'/cropimage/');  // Thư mục gốc của website

            // Upload hình ban đầu

            move_uploaded_file($_FILES["file"]["tmp_name"], SITE_PATH.$_FILES["file"]["name"]);

            CreateThumbImage(SITE_PATH.$_FILES["file"]["name"], SITE_PATH."thumb/".$_FILES["file"]["name"],$file_extension, 169, 169);

            CreateThumbImage(SITE_PATH.$_FILES["file"]["name"], SITE_PATH."small/".$_FILES["file"]["name"],$file_extension, 50, 50); 

            echo "Upload success!";

          }

          else

          {

            exit("File có duôi không hợp lệ!");     

          }

        }

?>

Đây là kết quả mình đạt được.

Thư mục source

Thư mục small

Thư mục thumb


Đây là link tải source ví dụ:  

Chúc bạn thành công.

Thứ Hai, 4 tháng 6, 2018

Viết Game Rắn Săn Mồi Bằng Html

Rắn ăn mồi tựa game đã từng hot trên những chiếc điện thoại đen trắng. Nay blog hướng dẫn bạn viết code game này trên nền tảng web. Ngôn ngữ code dùng chính là HTML Canvas để thiết kế game.

Demo:


Đầu tiên các bạn tạo 1 file HTML và nhập đoạn code sau:
>
<!DOCTYPE html>
<html>
<head>
<title></title>
<style>
  html, body {
    height: 100%;
    margin: 0;
  }
  body {
    background: black;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  canvas {
    border: 1px solid white;
  }
  </style>
</head>
<body>
<canvas width="400" height="400" id="game"></canvas>
<script>
 //Ở đây ta tạo ra bộ khung chứa game
var canvas = document.getElementById('game');
var context = canvas.getContext('2d');
var grid = 16;
// khởi tạo đối tượng rắn là 1 ô vuông
var snake = {
  x: 160, //vị trí của snake theo hướng x,y
  y: 160,
  dx: grid, //hướng di chuyển theo phương x hoặc y,ở đây khi start game
 //snake sẽ di chuyển theo x direction với value = 16
  dy: 0,     
  cells: [],
  maxCells: 4
};
var count = 0;
var apple = {
  x: 320,
  y: 320
};
function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min)) + min;
}
// game loop
function loop() {
//hàm này giống như setTimeout, sẽ gọi lại hàm loop khi loop thực thi xong
  requestAnimationFrame(loop);
  // slow game loop to 15 fps instead of 60 - 60/15 = 4
  if (++count < 4) {
    return;
  }
  count = 0;
  context.clearRect(0,0,canvas.width,canvas.height);
  snake.x += snake.dx; // mỗi loop rắn sẽ di chuyển thêm 1dx đơn vị
  snake.y += snake.dy;
  // khi snake đụng tường sẽ chạy lại từ edge đối diện
  if (snake.x < 0) {
    snake.x = canvas.width - grid;
  }
  else if (snake.x >= canvas.width) {
    snake.x = 0;
  }
  if (snake.y < 0) {
    snake.y = canvas.height - grid;
  }
  else if (snake.y >= canvas.height) {
    snake.y = 0;
  }
  // Phương thức unshift sẽ thêm một hoặc nhiều phần tử vào đầu mảng
  snake.cells.unshift({x: snake.x, y: snake.y});
  // thêm 1 ô vuông phía trc thì phải remove 1 cái phía sau để snake move dc.
  if (snake.cells.length > snake.maxCells) {
    snake.cells.pop();
  }
  // draw apple
  context.fillStyle = 'red';
  context.fillRect(apple.x, apple.y, grid-1, grid-1);
  // draw snake
  context.fillStyle = 'green';
  snake.cells.forEach(function(cell, index) {
    context.fillRect(cell.x, cell.y, grid-1, grid-1);
    // snake ate apple
    if (cell.x === apple.x && cell.y === apple.y) {
      snake.maxCells++;
      apple.x = getRandomInt(0, 25) * grid;
      apple.y = getRandomInt(0, 25) * grid;
    }
    // check va chạm khi rắn đụng đuôi
    for (var i = index + 1; i < snake.cells.length; i++) {
      // va chạm thì reset game
      if (cell.x === snake.cells[i].x && cell.y === snake.cells[i].y) {
        snake.x = 160;
        snake.y = 160;
        snake.cells = [];
        snake.maxCells = 4;
        snake.dx = grid;
        snake.dy = 0;
        apple.x = getRandomInt(0, 25) * grid;
        apple.y = getRandomInt(0, 25) * grid;
      }
    }
  });
}
//bắt sự kiện bàn phím ấn xuống
document.addEventListener('keydown', function(e) {
  // lọc sự kiện keydown để rắn không di ngược lại
  if (e.which === 37 && snake.dx === 0) {
    snake.dx = -grid;
    snake.dy = 0;
  }
  else if (e.which === 38 && snake.dy === 0) {
    snake.dy = -grid;
    snake.dx = 0;
  }
  else if (e.which === 39 && snake.dx === 0) {
    snake.dx = grid;
    snake.dy = 0;
  }
  else if (e.which === 40 && snake.dy === 0) {
    snake.dy = grid;
    snake.dx = 0;
  }
});
requestAnimationFrame(loop);
</script>
</body>
</html>


Lưu code lại và test!